Results 1 to 6 of 6

Thread: How do I transfer in-memory data from one program to another easilly?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    How do I transfer in-memory data from one program to another easilly?

    I've created these two test programs. Basic operation is this.

    One defines a Long type variable "a" and assigns it a value.
    Then the second one is run and it establishes a TCP connection to the first (they both are using Winsock for the initial connection).
    Then the first one uses VarPtr to get the address of the variable "a" and sends this memory address over the TCP connection to the second program.
    Then the second program attempts to directly access the value stored in the variable "a" from the first program, using the CopyMemory API command.
    But then that second program crashes (as in it completely crashes the VB6 IDE that the program was running from, just as if I'd given CopyMemory an invalid memory address, but it's VERY valid, as it was taken directly from the first program).

    Here is the code for the first program.
    Code:
    Dim a As Long
    Private Sub Form_Load()
    a = 12345
    Server.Listen
    End Sub
    
    Private Sub Server_ConnectionRequest(ByVal requestID As Long)
    Server.Close
    Server.Accept requestID
    End Sub
    
    Private Sub Server_DataArrival(ByVal bytesTotal As Long)
    Dim Text As String
    Server.GetData Text
    If Text = "Ready" Then Server.SendData VarPtr(a)
    End Sub
    Here's the code for the second program.
    Code:
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    
    Private Sub Client_Connect()
    Client.SendData "Ready"
    End Sub
    
    Private Sub Client_DataArrival(ByVal bytesTotal As Long)
    Dim Address As Long
    Dim Value As Long
    Client.GetData Value
    CopyMemory Value, ByVal Address, 4
    MsgBox Value
    End Sub
    
    Private Sub Form_Load()
    Client.Connect "127.0.0.1", 12000
    End Sub
    Using memory like this so that the programs could share memory addresses would be faster for copying large quantities of data like raw pixel data from pictures, than it would be to send the all the data over TCP. TCP should just be used to share the numbers that are the memory addresses. This way I could have a collection of image processing tools, each its own program (exe file) but they could ALL have access to the same image data in memory. For example I could have imageprocessor.exe and separately imageloaderplugin.exe, and the first program would run the second, the second program would load the image, and store it in memory, and then the first program would get the image by reading the raw pixel data that was stored in memory by the first program.

    I don't understand why it isn't working. I don't know why VB6 keeps crashing. Also, if there's an easier way to accomplish sharing of data between programs (without the saving of a temporary file), then please let me know.
    Last edited by Ben321; Jan 10th, 2013 at 03:22 PM.

  2. #2
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: How do I transfer in-memory data from one program to another easilly?


  3. #3
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I transfer in-memory data from one program to another easilly?

    From About Memory Management:

    Each process on 32-bit Microsoft Windows has its own virtual address space that enables addressing up to 4 gigabytes of memory. Each process on 64-bit Windows has a virtual address space of 8 terabytes. All threads of a process can access its virtual address space. However, threads cannot access memory that belongs to another process, which protects a process from being corrupted by another process.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  4. #4
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: How do I transfer in-memory data from one program to another easilly?

    um... are both projects running on the same machine?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  5. #5
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: How do I transfer in-memory data from one program to another easilly?

    Interprocess Communications (Windows) offers a rundown of the available options. Each has its advantages and disadvantages.

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    Re: How do I transfer in-memory data from one program to another easilly?

    I decided to use named pipes. So I created this test program to make sure my understanding of how it works is sound. Unfortunately it doesn't work as expected. See the code below:
    Code:
    Private Declare Function CreateNamedPipe Lib "kernel32.dll" Alias "CreateNamedPipeA" (ByVal lpName As String, ByVal dwOpenMode As Long, ByVal dwPipeMode As Long, ByVal nMaxInstances As Long, ByVal nOutBufferSize As Long, ByVal nInBufferSize As Long, ByVal nDefaultTimeOut As Long, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long
    Private Declare Function WriteFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByRef lpOverlapped As OVERLAPPED) As Long
    Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As OVERLAPPED) As Long
    Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
    
    Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
    End Type
    
    Private Type OVERLAPPED
        ternal As Long
        ternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
    End Type
    
    
    
    Private Sub Form_Load()
    Dim NPipeHandle As Long
    Dim OL As OVERLAPPED 'I'm going to leave this blank so defaults are used
    Dim Sec As SECURITY_ATTRIBUTES 'I'm going to leave this blank so defaults are used
    Dim a As Long
    Dim b As Long
    
    
    a = 12345
    
    NPipeHandle = CreateNamedPipe("\\.\pipe\MyPipe", 3, 0, 1, 4, 4, 50, Sec) 'it is configured to work duplex, have no more than one instance, have 4 byte input and 4 byte output buffers, and have a 50ms waiting time.
    Print NPipeHandle
    
    z = 0
    Print WriteFile(NPipeHandle, a, 4, z, OL)
    Print z
    
    z = 0
    Print ReadFile(NPipeHandle, b, 4, z, OL)
    Print z
    Print b
    
    CloseHandle NPipeHandle
    End Sub
    The first print statement shows a number, indicating the handle of the named pipe.
    The print statements after that all show 0, indicating a complete failing of the rest of the program.

    Please tell me why this isn't working.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width