Announcement

Collapse
No announcement yet.

Inter-process communications using CopyMemory

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

  • Inter-process communications using CopyMemory

    Ive created a DLL that, when called, needs to scan files and return information about them as it goes. Basically, my VB program calls my PB DLL , and the DLL should then scan my drive C, and if it finds any files that match the filename, it should use CopyMemory to send a message to my VB exe.

    Ive ported this code over from VB ... im sure its about 99.9% correct, but there's something thats not right!
    Can somebody please help ?

    %WM_COPYDATA = &H4A
    DIM cdCopyData AS COPYDATASTRUCT
    DIM ThWnd AS LONG
    DIM byteBuffer(1 TO 255) AS BYTE
    DIM strTemp AS STRING
    DIM i AS LONG
    DIM JZ AS LONG
    ' Get the hWnd of the target application
    ThWnd = FindWindow("", "My DDE Target")
    strTemp = "Hello DDE target!"

    ' Copy the string into a byte array, converting it to ASCII
    JZ = CopyMemory(byteBuffer(1), BYVAL strTemp, LEN(strTemp))
    cdCopyData.dwData = 3
    cdCopyData.cbData = LEN(strTemp) + 1
    cdCopyData.lpData = VARPTR(byteBuffer(1))
    i = SendMessage(ThWnd, %WM_COPYDATA, 0)


    'Many thanks!

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

  • #2
    Code:
    DECLARE SUB CopyMemory LIB "KERNEL32.DLL" ALIAS "RtlMoveMemory" (lpDest AS ANY, lpSource AS ANY, BYVAL cb&)
    
    ' SEND PART
    DIM cds As COPYDATASTRUCT                      
    DIM Buf(255) AS BYTE
    Buff$ = "The string to send"
    CALL CopyMemory(Buf(0), BYVAL STRPTR(Buff$), LEN(Buff$))
    cds.dwData = 3
    cds.cbData = LEN(Buff$) + 1
    cds.lpData = VARPTR(Buf(0))
    CALL SendMessage(hFound&, %WM_COPYDATA, 0, VARPTR(cds))
    
    
    'RECEPT PART
        CASE %WM_COPYDATA
             DIM cds AS COPYDATASTRUCT
             DIM Buf(255) AS BYTE
             CALL CopyMemory(cds, BYVAL lParam&, SIZEOF(cds))
             SELECT CASE cds.dwData
             CASE 1
             CASE 2
             CASE 3 
                Call CopyMemory(buf(0), BYVAL cds.lpData, cds.cbData)
                Buff$ = PEEK$(VARPTR(buf(0)), UBOUND(Buf) - LBOUND(Buf) + 1)
                So& = INSTR(Buff$, CHR$(0))
                IF So& THEN Buff$ = LEFT$(Buff$, So& -1)
                MsgBox Buff$
             END SELECT
    ------------------
    Patrice Terrier
    mailto[email protected][email protected]</A>
    Patrice Terrier
    www.zapsolution.com
    www.objreader.com
    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

    Comment


    • #3
      Patrice, I thank you kindly for helping me out, but I am still having no luck! :-/
      I don't need to receive any messages, just send (but i'll keep your code handy in case I ever do need to receive)
      This is what i've got now:

      DIM cds AS COPYDATASTRUCT
      DIM Buf(255) AS BYTE
      DIM hFound&
      Buff$ = "Yes come in my program, do you read me?"
      cds.dwData = 3
      cds.cbData = LEN(Buff$) + 1
      cds.lpData = VARPTR(Buf(0))
      CALL MoveMemory(Buf(0), BYVAL STRPTR(Buff$), LEN(Buff$))
      hFound& = FindWindow("", "My DDE Target")
      CALL SendMessage(hFound&, %WM_COPYDATA, 0, VARPTR(cds))

      It looks spot on to me, but it GPF's when I call it , with The memory at 0x000000 could not be written
      Any ideas?
      Thanks once again!

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

      Comment


      • #4
        The 1st parameter of MoveMemory() looks suspect - depending on the declaration of MoveMemory() you are using, you may have to explicitly pass the pointer to the 1st element of the byte array or the compiler may be passing the value in the 1st parameter instead! Try this:

        Code:
        CALL MoveMemory(BYVAL VARPTR(Buf(0)), BYVAL STRPTR(Buff$), LEN(Buff$))
        or just use native PB code instead:

        Code:
        POKE$ VARPTR(Buf(0)), LEFT$(Buff$, UBOUND(Buf()) - LBOUND(Buf()))
        If this does not help, you need to find the exact point where the GPF is occuring. Interlacing MSGBOX statements between each line in the DLL should help identify the exact point it fails.

        That said, it could be your VB code is having problems when processing the %WM_COPYDATA message... you have not posted enough code to be 100% sure of where the problem is occuring. You can check this by writing a small PB EXE that uses the DLL instead, and use Patrices 'receive' code to test the DLL out.

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

        Comment


        • #5
          SUCCESS!!
          A million thanks (once again) to Lance and Patrice. I had to use parts of both of your code samples to get it to work Here is the code that I am successfully using to send a message to my VB Snail

          Code:
          FUNCTION SEND2VB() EXPORT AS INTEGER
          ON ERROR RESUME NEXT
          DIM cds AS COPYDATASTRUCT
          DIM Buf(255) AS BYTE
          DIM hFound&
           hFound& = FindWindow("", "DDE Target Window")
           Buff$ = "Hello, anybody there?"
           CALL MoveMemory(BYVAL VARPTR(Buf(0)), BYVAL STRPTR(Buff$), LEN(Buff$))
           cds.dwData = 3
           cds.cbData = LEN(Buff$) + 1
           cds.lpData = VARPTR(Buf(0))
           CALL SendMessage(hFound&, %WM_COPYDATA, 0, VARPTR(cds))
           FUNCTION = 1    'Success, cheers Lance/Patrice!
          END FUNCTION
          Lance, ive only known you for two days and I already feel like I'll be saying Thanks Mate! every week for the rest of my life, dont you hate that?

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

          Comment


          • #6
            No worries, Bluey!

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

            Comment


            • #7
              One quick note in the wake of this thread (and your referral post in another thread here)...

              The title of this thread should have been "intra-process communication", rather than "inter-process communication".

              Intra-process is much easier than Inter-process: The former takes place within a single process address space, and the latter requires the assistance of Windows to use special temporary memory mapping techniques to take data from one process and make it available to another process.


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

              Comment


              • #8
                Lance, you are absolutely correct: re intra vs. inter.
                Additionally, I should've referred to RtlMoveMemory, not it's alias of CopyMemory !
                (I'll get PowerBasic worked out - just let me master English first)





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

                Comment

                Working...
                X