Announcement

Collapse
No announcement yet.

Possible bug in PowerBASIC's implementation of Fixed-length strings

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Michael--

    It would normally be something like:

    LongVarArr(0) = CVL("xc" + CHR$(0,0))

    However, if you have to go through a special group of assignment statements like this, I probably wouldn't waste the time here. I'd most likely put any extra code on the PowerBASIC side, as it will likely be much faster. I just tossed this out as a general idea which might help... never know about all the circumstances.

    Best regards,

    Bob

    Comment


    • #22
      Originally posted by Michael Mattias View Post
      It is?
      It is for anyone who hasn't used it. Perhaps you would care to post an actual example demostrating how to use it.

      =========================================================
      "Perfect love is rare indeed
      for to be a lover will require that you continually have:
      the subtlety of the very wise,
      the flexibility of the child,
      the sensitivity of the artist,
      the understanding of the philosopher
      the acceptance of the saint,
      the tolerance of the scholar
      and the fortitude of the certain."
      Leo Buscaglia
      =========================================================
      It's a pretty day. I hope you enjoy it.

      Gösta

      JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
      LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

      Comment


      • #23
        It is for anyone who hasn't used it. Perhaps you would care to post an actual example demostrating how to use it.
        MKL$() allows you to assign the four bytes of a long integer to a string variable
        CVL() allows you to assign the value of any four bytes to a long integer variable

        Code:
          LOCAL  pL AS LONG PTR, L AS LONG, S AS STRING 
        
          LET L =  12345&
          LET S  =  MKL$(L) 
          LET   pl =  STRPTR (S)    ' point to the string 
          MSGBOX  @Pl
        If you want to look at it another way, a UNION is a good example. Four bytes is four bytes... you can look at those four bytes as a string or a long integer.
        Code:
        UNION LongUnion
          L   AS LONG
          S   AS STRING * 4 
        END UNION
        
           LOCAL U AS LongUnion 
           U.S  = MKL$(12345&) 
           MSGBOX   FORMAT$(U.L)
        I guess you don't use the CVx/MKx$ functions as much as you did since UDTs replaced Ye Olde "FIELD" statements used in older BASIC to access numbers stored in disk files, but they can still be useful functions to have around.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #24
          Originally posted by Michael Mattias View Post
          I guess you don't use the CVx/MKx$ functions as much as you did since UDTs replaced Ye Olde "FIELD" statements used in older BASIC to access numbers stored in disk files, but they can still be useful functions to have around.

          MCM
          No, you are right. Haven't used them (in Field) in a long time. Dunno why/how I could forget. Started with Fields back when it was a max of 255 bytes and records had to be a multiple of 255 (5 51 byte records, for example of "efficient" storage or later data divisible by 255). (First on tape storage then using 60k capacity floppies so compacting was important). (The proper term is Boundry - Just reminded of that when reading another thread,)

          Thanks the reminder, M. A year or so ago when John G and I were playing around with the Word Connection puzzle solver (Programming Forum), he was using packed strings for the data and this dummy didn't make the Mk/Cv connection then about packing strings. Now I see it clearly. Or maybe I don't. Close enough anyway.

          ==================================
          "The difference between
          'involvement' and 'commitment'
          is like a ham-and-eggs breakfast:
          the chicken was 'involved'
          the pig was 'committed'."
          unknown
          ==================================
          Last edited by Gösta H. Lovgren-2; 29 Mar 2009, 09:46 PM. Reason: "You have to set Rules *Boundries* and Leemitations." - Cesar Milan
          It's a pretty day. I hope you enjoy it.

          Gösta

          JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
          LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

          Comment


          • #25
            Hi Bob:
            I was wondering: In your March 28th 5 PM post you state: "A 4 element array is four of those pointers which could point anywhere, because each could be any length, including nul, in which case the pointer would be zero. Effectively, you have string pointers with two levels of indirection." Is there any place in memory where those 4 pointers are in contiguous locations? Thanks! May you have a blessed day.
            Sincerely,
            Michael D Fitzpatrick

            Comment


            • #26
              Hi Michael,

              Assuming,,,

              DIM xx$(1 TO 4)

              This creates an array of four dynamic string variables. These four string variables are stored in contiguous memory locations. Each of these variables consists of of a 32-bit (4-byte) pointer to the actual string data. If the string is nul (zero-length) the pointer is zero (0).

              VARPTR(xx$(1)) returns the address (location) of that string variable. The next 3 array members follow in memory.

              STRPTR(xx$(1)) returns the address of the string data, or zero if nul.

              STRPTR(xx$(1)) is equal to the pointer at VARPTR(xx$(1))

              x& = PEEK(LONG, VARPTR(xx$(1)))
              y& = STRPTR(xx$(1))
              x& and y& are always equal.

              Best regards,

              Bob Zale
              PowerBASIC Inc.

              Comment


              • #27
                Missing Declaration

                Hi Bob:
                I am having some difficulty understanding your post.
                1) When I tried compiling just this much in PowerBASIC:
                DIM xx$(1 TO 4)
                xx(1) = "xc"
                xx(2) = "SR"
                xx(3) = "DI"
                xx(4) = "CO"
                I got the compiler message: "Missing declaration: xx"
                Did you mean DIM xx(1 TO 4) As String?
                And did you mean for this DIM to reside in a PowerBASIC source or in an Excel VBA procedure (as per my situation)?
                2) If we are dealing with arrays of strings, why would you have:
                x& = PEEK(LONG, VARPTR(xx$(1)))
                y& = STRPTR(xx$(1))
                Wouldn't x& and y& be of type LONG? (Perhaps I am missing something here.) How would those two statements (and any other relevant code) have to be modified to deal with strings instead of integers? Thanks for your kind help. May you have a blessed day.
                Sincerely,
                Michael Fitzpatrick
                Last edited by Michael Fitzpatrick; 4 Apr 2009, 11:29 PM. Reason: typo

                Comment


                • #28
                  I didn't create code which was intended to be used anywhere in particular. I just answered your question and gave you some example pseudo-code to demonstrate the principles.

                  DIM xx$(...) creates, allocates, and initializes a dynamic string array named xx$(). There is no exclusivity to the name, so you must reference it with the "$" type identifier to tell it apart from xx%() and xx#() and others.

                  DIM xx(...) AS STRING creates, allocates, and initializes a dynamic string array. Additionally, the AS STRING declares that the name xx is exclusive to this particular name and will not be used for another array in this scope and context. It can then be referenced without a type identifier as xx(). Now, xx() and xx$() may be used interchangeably. They refer to the same array data, bevause you told the compiler that any use of the ambiguous name xx() should be interpreted as the dynamic string array named by xx().

                  The variables x& and y& are long integers. VARPTR() and STRPTR() return a numeric value which tells you the location (address) of a variable and string data respectively. An address is a numeric value, not a string, so the address must be assigned to a numeric variable.

                  You asked me where in memory a particular set of data may be found. The concept of "where" requires a numeric answer because that is the way an address (location) is represented. The code I gave you showed a generic way to obtain the address of a variable or string data.

                  Bob Zale
                  PowerBASIC Inc.

                  Comment


                  • #29
                    For example, the string array whose elements are:
                    OfcArry(0) = "xc"
                    OfcArry(1) = "DIR"
                    OfcArry(2) = "SR"
                    . . .
                    OfcArry(49) = "COO"

                    can instead be represented by an array of integers whose elements are:
                    IOfcArry(0) = 4
                    IOfcArry(1) = 1
                    IOfcArry(2) = 2
                    . . .
                    IOfcArry(49) = 3
                    Going back to your idea above and Bob's subsequent suggestion: Like you say, the integers will be faster. But rather than using 1 thru 4 to represent your strings, because the strings are short--3 characters max--they can be immediately converted beforehand to their 4-byte capable LONG equivalents and likely save a re-conversion step later. The IOfcArr() elements become:
                    Code:
                    IOfcArry(0) = 25464    '"xc" = &h6378 = 25464. &h63 = "c" and &h78 = "x" but stored reversed (aka little endian). 
                    IOfcArry(1) = 5392708  '"DIR"
                    IOfcArry(2) = 21075    '"SR"
                    . . .
                    IOfcArry(49) = 5197635 '"COO"
                    The IOfcArr() now holds the exact characters of the strings but will be processed in the fastest way as LONG's. I'm with Gösta on this one being a rather advanced technique and hopefully this doesn't sound too obtuse.

                    Comment


                    • #30
                      For more clarity, here is a compilable example:
                      Code:
                      #COMPILE EXE
                      #DIM ALL
                      
                      FUNCTION PBMAIN () AS LONG
                        LOCAL msgString AS STRING
                        
                        msgString = STRING$(200, ".")  '50 elements * 4 bytes per element = 200 bytes needed
                        DIM IOfcArry(49) AS LONG AT STRPTR(msgString) 'overlay array onto msgString. (again, rather advanced technique)
                        
                           IOfcArry(0) = 25464    '"xc" = &h6378 = 25464. &h63 = "c" and &h78 = "x" but stored reversed (aka little endian).
                           IOfcArry(1) = 5392708  '"DIR"
                           IOfcArry(2) = 21075    '"SR"
                           '. . .
                           IOfcArry(49) = 5197635 '"COO"
                           REPLACE ANY $NUL WITH $SPC IN msgString 'gets rid of $NUL characters so we can print full string
                         ? msgString              'now you can see how your strings are stored properly
                      END FUNCTION

                      Comment


                      • #31
                        Not that diversion is necessarily a bad thing, but I think we may have forgotten the 'conditions of contest' here...

                        The problem is NOT to "do something" in PowerBASIC to allow a PB-written function in a DLL to understand what has been passed to it; the problem is finding the best way to express and work with whatever VBA is passing to that DLL-based function.

                        When you control both sides (the passer and the passee, so to speak) many things are possible... but when you don't control one side or the other, the number of things which can be made to work tends to be somewhat more limited.

                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #32
                          Originally posted by Michael Fitzpatrick View Post
                          Hi Bob:
                          I am having some difficulty understanding your post.
                          1) When I tried compiling just this much in PowerBASIC:
                          DIM xx$(1 TO 4)
                          xx(1) = "xc"
                          xx(2) = "SR"
                          xx(3) = "DI"
                          xx(4) = "CO"
                          I got the compiler message: "Missing declaration: xx"
                          Michael Fitzpatrick
                          Michael,

                          You don't show your actual code used (always preferred on this forum) so it's difficult to determine exactly what the problem is. I'd bet you have a "#Dim All" at the top of your code (Highly reccoed for all code). Try
                          Code:
                          '...
                          Local xx$()  '<<<<Add this befire Dimming **************
                          Dim (xx$(1 to 4)
                          '...
                          And then run your program.


                          ===============================================
                          "It is better to be feared than loved,
                          if you cannot be both."
                          Niccolo Machiavelli (1469-1527), "The Prince"
                          ===============================================
                          It's a pretty day. I hope you enjoy it.

                          Gösta

                          JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                          LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                          Comment


                          • #33
                            Hi Bob:
                            Thanks for your very helpful explanation. I will be studying this entire thread over the next week or so. I see that I am still on the lower portion of the learning curve. May you have a blessed day.

                            Sincerely,

                            Michael D Fitzpatrick

                            Comment

                            Working...
                            X