Announcement

Collapse
No announcement yet.

Problem? VB string byRef to PB function modified via RTLMoveMemory

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

  • Problem? VB string byRef to PB function modified via RTLMoveMemory

    Hi
    Im not sure if this is a problem or not. Could someone explain
    this to me?

    The following function is called from VB and the string
    being passed in the Text argument = ""

    Code:
    Function PassStringByRef (ByRef Text as string) Export as Long
         Dim s1 as string
         Dim s2 as string
         
         s1 = "Hello"
         MoveMemory STRPTR(Text), STRPTR(s1), Len(s1)
         
         Msgbox Text  ' <-- Produces "Hello" in message box
         Text = Text & " added"  ' <-- Produces " added" in message box
         
         s2 = Text
         MSGBOX s2    ' <-- Produces "Hello" in message box
         s2 = s2 & " added"  
         Msgbox s2    ' <-- Produces " added" in message box
         
         Functon = 0  ' <-- The results of Text back on the VB side = "" 
      
    End Function
    Obviously the problem is a result of the dynamic string's length
    not being updated when MoveMemory is used on it and can be
    worked around by just using Space$() on the string ahead of time.
    But is this normal behavior? I tested this scenario under VB and
    the strings length is correctly updated after the MoveMemory
    operation.

    But it seems odd that Msgbox would show "Hello" at all. Sorta
    like "now you see it, now you dont." It also seems odd that
    when actually assigning Text to s1, that s1 takes on the exact
    characteristics of Text.

    Just to be clear, this isnt an issue for me since i now just
    use Space$() to presize the string. Im just posting this message
    for clarification whether this is a bug or by design.

    Thanks
    -Mike


    [This message has been edited by Mike Joseph (edited August 28, 2000).]

  • #2
    this is an faq question: http://www.powerbasic.com/support/pb...hread.php?t=26




    ------------------
    lance
    powerbasic support
    mailto:[email protected][email protected]m</a>
    Lance
    mailto:[email protected]

    Comment


    • #3
      I didnt really see anything at that link which seemed relevant
      to this. This has nothing to do with passing args from VB to PB
      and back. This is about using RLTMovememory on a dynamic string
      in PB. I just found it odd that MsgBox shows the string yet when
      you try to append to it, the original string is lost. Clearly though
      its adviseable to just presize a string using Space$ or String$.
      The following code causes a GPF when trying to append to the string.

      Code:
      #COMPILE EXE
      #REGISTER NONE
      #DIM ALL
      #INCLUDE "win32api.inc"
      FUNCTION PBMAIN()
          DIM s AS STRING
          DIM s1 AS STRING
          DIM s2 AS STRING
          
          s = ""
          s1 = STRING$(1000,"A")
          MoveMemory STRPTR(s), STRPTR(s1), LEN(s1)
         
          MSGBOX s
          MSGBOX s & " added"     <- GPF here
         
      END FUNCTION
      ------------------

      Comment


      • #4
        Mike,

        To copy source bytes to a destination, you have to make sure that the
        copied bytes don't step on important stuff. So I believe you have to
        assign destination space before using MoveMemory or you risk getting
        GPF errors. In your last post, you tried to copy bytes to a string
        with no length.

        As for your first post, assuming that you assigned string space in VB,
        your problem is probably with the way VB passes strings. I don't know
        that much about VB. I used PowerBasic to call your function and every
        thing seems to work as expected, as demonstrated in the code below.

        At least that's the way I see it. Hope this helps.


        Code:
        #COMPILE EXE
        #DIM ALL
        #INCLUDE "win32api.INC"
        DECLARE FUNCTION PassStringByRef (BYREF TEXT AS STRING) AS LONG
        
        FUNCTION PBMAIN
           LOCAL txt AS STRING
           txt = SPACE$(10)
           PassStringByRef txt
        END FUNCTION
        
        FUNCTION PassStringByRef (BYREF txt AS STRING) AS LONG
           DIM s AS STRING
           DIM s1 AS STRING
           DIM s2 AS STRING
        
           s1 = "Hello"
           MoveMemory STRPTR(txt), STRPTR(s1), LEN(s1)
           MSGBOX txt            ' <-- Produces "Hello"
           txt = txt + " added"  ' <-- Produces "hello      added"
           MSGBOX txt
        
           s2 = txt
           MSGBOX s2    ' <-- Produces "Hello      added"
           s2 = s2 & " added"
           MSGBOX s2    ' <-- Produces "Hello      added added"
        
           s = SPACE$(1000)  'Need to assign destination space here
           s1 = STRING$(1000,"A")
           MoveMemory STRPTR(s), STRPTR(s1), LEN(s1)
           MSGBOX s
           MSGBOX s & " added"     '<- no GPF here now
        
           FUNCTION = 0  ' <-- The results of Text back on the VB side = ""
        END FUNCTION
        ------------------

        Comment


        • #5
          I dont belive that you can use RTLMoveMemory in Visualbasic, the way you
          describe it.
          This is the Powerbasic code
          Code:
          Function PbMain()As Long
            a$="123456789012345678901234567890"
            b$="Hello"
            MoveMemory StrPtr(a$), StrPtr(b$), Len(b$)
            Print a$
            waitkey$
          End Function
          This is the code you will need in VB to do the same thing.
          Code:
          Private Sub Form_Load()
            a$ = "123456789012345678901234567890"
            b$ = "Hello"
            MoveMemory StrPtr(a$), StrPtr(b$), 2 * Len(b$)
          
          End Sub
          The result will be the same => Hello6789012345678901234567890
          Because either in VB or in PB RTLMoveMemory updates the dynamic strings
          it only copies bytes from one area in memory to another..
          If the destination string is too short, you will owerwrite something important.....

          PS: Why do you need to use MoveMemory ??


          ------------------
          Fred
          mailto:[email protected][email protected]</A>
          http://www.oxenby.se



          [This message has been edited by Fred Oxenby (edited August 29, 2000).]
          Fred
          mailto:[email protected][email protected]y.se</A>
          http://www.oxenby.se

          Comment


          • #6
            Thanks for the comments.

            Fred, i need to use MoveMemory because Im copying data from a portion
            of a page of virtual memory. I track the address offsets and
            lengths of the data I need to read back in.

            I suppose I could just use Peek$. (still need to get used to
            all these handy, built in PB functions)

            -Mike


            ------------------

            Comment


            • #7
              Well, this is how I should do it...
              Code:
              #Compile DLL
              #Include "Win32Api.inc"
              
              Function GetStringByRef()Export as string
              Local TmpStr     as string
              Local VirtAdress as long  
              Local VirtLen    as long
                ..get your virtual adress and length...
                TmpStr = PEEK$(VirtAdress,VirtLen)
                ..manipulate your 'virtual data'
                TmpStr = TmpStr & " This is added to your virtual page"
                Function = TmpStr
              End Function
                
              ..or
               
              Function PassStringByRef(ByRef Text$) Export as long
              Local VirtAdress as long  
              Local VirtLen    as long
                ..get your virtual adress and length...
                Text$ = PEEK$(VirtAdress,VirtLen)
                'or if you use MoveMemory
                'Text$=Space$(VirtLen)
                'MoveMemory StrPtr(Text$),VirtAdress,VirtLen
                ..manipulate your 'virtual data'
                Text$ = Text$ & " This is added to your virtual page"
                Function = 0
              End Function
              VB-example:
              Code:
               MyVirtPage$ = GetStringByRef()
                
               MyVirtPage$ = ""
               if PassStringByRef(MyVirtPage$)= 0 then
                Debug.Print "Alles OK"
               end if

              ------------------
              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Comment


              • #8
                When you use MoveMemory, the amount of information that gets copied is based on the length you specify. When you copy to a string that isn't large enough to hold that many bytes, you'll either get a GPF or end up overwriting something else in memory.

                The reason the message box works is presumably that there happened to be a CHR$(0) at the end of the string. The MessageBox API call is presumably looking for the CHR$(0) marker rather than the string length count, which won't be set by MoveMemory.


                ------------------
                Tom Hanlin
                PowerBASIC Staff

                Comment


                • #9
                  Exactly... hence the reason I pointed out the FAQ on VB strings.

                  ------------------
                  Lance
                  PowerBASIC Support
                  mailto:[email protected][email protected]</A>
                  Lance
                  mailto:[email protected]

                  Comment


                  • #10
                    mike, this thread may be of use: http://www.powerbasic.com/support/pb...ead.php?t=2620
                    (re: inter-process communications using copymemory (rtlmovememory))

                    -

                    Comment

                    Working...
                    X