|
From: santosh.pjb on 2 Jun 2008 17:29 I have a win32 dll (VC6) and a VB6 exe. The dll gets loaded (and a specified single parameter function is called) by a 3rd party app - when an event of interest occurs. The 3rd party app uses the __cdecl calling convention and passes a single LPSTR argument to the dll funtion. I now want to add some code in that dll fn to pass the string to the VB exe. I haven't done much win32 programming recently and more importantly haven't touched VB in nearly a decade so looking for some advice on how to proceed. After a bit of googling, I decided to use FindWindow() and SendMessage() on the VC dll side, and subclassing the WindowProc on the VB side to receive the message. This seems to be working as the VB exe receives the message, but it doesn't receive the string being passed or to be more specific it recieves a pointer to some garbage. This is what the code looks like VC6 DLL :- long foo(LPSTR id){ FindWindow(NULL,"VBApp") char cTemp[50]; strcpy_s(cTemp,cid); h = FindWindow(NULL, "Parse"); SendMessage(h, WM_USER + 234, NULL, (LPARAM) &cTemp); } VB exe :- WindowProc(...) If (uMsg = WM_USER + 234) Then sLen = lstrlen(lParam) sString = Space$(sLen) CopyMemory ByVal sString, ByVal lParam, sLen DebugPrint ("Received: " & sString) << ====== Prints garbage DoSomething(sString) End If CopyMemory is kernel32 RtlMoveMemory Any advice is greatly appreciated, Thanks
From: Karl E. Peterson on 2 Jun 2008 19:19 santosh.pjb(a)gmail.com wrote: > This seems to be working as the VB exe receives the message, but it > doesn't receive the string being passed or to be more specific it > recieves a pointer to some garbage. You need to pass a pointer to the buffer directly, because otherwise you get trampled by UniMess. To dereference string pointers passed to VB: Public Function PointerToStringA(ByVal lpStringA As Long) As String Dim Buffer() As Byte Dim nLen As Long If lpStringA Then nLen = lstrlenA(ByVal lpStringA) If nLen Then ReDim Buffer(0 To (nLen - 1)) As Byte CopyMemory Buffer(0), ByVal lpStringA, nLen PointerToStringA = StrConv(Buffer, vbUnicode) End If End If End Function Public Function PointerToStringW(ByVal lpStringW As Long) As String Dim Buffer() As Byte Dim nLen As Long If lpStringW Then nLen = lstrlenW(lpStringW) * 2 If nLen Then ReDim Buffer(0 To (nLen - 1)) As Byte CopyMemory Buffer(0), ByVal lpStringW, nLen PointerToStringW = Buffer End If End If End Function For more information helping VC and VB "play nice" together, here's an obscure text file that came with VB5 way back when: Microsoft: Developing DLLs for VB5 http://vb.mvps.org/tips/vb5dll.asp -- ..NET: It's About Trust! http://vfred.mvps.org
From: Brian Muth on 2 Jun 2008 19:28 You are trying to pass the address of the string across process boundaries. This is pointless, since the address is meaningless to the target process since every process has its own address space. Using DCOM would be the best solution here. Your VB6 executable should be created not as a "Standard EXE" but an "ActiveX EXE". You can then define a class module that can be instantiated by the C++ code as a remote object, and call the functions you define, including one that presumably takes the string as a parameter. Unfortunately, the learning curve here is pretty significant, and I'm wondering if you would consider turning to a colleague or outside professional with DCOM experience to cruft this up for you. Otherwise, you will have weeks, if not months of work ahead of you. (my $0.02) <santosh.pjb(a)gmail.com> wrote in message news:5f3dff75-16c9-4a7d-b0d3-f5912b583471(a)w34g2000prm.googlegroups.com... >I have a win32 dll (VC6) and a VB6 exe. The dll gets loaded (and a > specified single parameter function is called) by a 3rd party app - > when an event of interest occurs. The 3rd party app uses the __cdecl > calling convention and passes a single LPSTR argument to the dll > funtion. I now want to add some code in that dll fn to pass the string > to the VB exe. > > I haven't done much win32 programming recently and more importantly > haven't touched VB in nearly a decade so looking for some advice on > how to proceed. > > After a bit of googling, I decided to use FindWindow() and > SendMessage() on the VC dll side, and subclassing the WindowProc on > the VB side to receive the message. > > This seems to be working as the VB exe receives the message, but it > doesn't receive the string being passed or to be more specific it > recieves a pointer to some garbage. > > This is what the code looks like > VC6 DLL :- > long foo(LPSTR id){ > FindWindow(NULL,"VBApp") > char cTemp[50]; > strcpy_s(cTemp,cid); > h = FindWindow(NULL, "Parse"); > SendMessage(h, WM_USER + 234, NULL, (LPARAM) &cTemp); > } > > VB exe :- > WindowProc(...) > If (uMsg = WM_USER + 234) Then > sLen = lstrlen(lParam) > sString = Space$(sLen) > CopyMemory ByVal sString, ByVal lParam, sLen > DebugPrint ("Received: " & sString) << ====== Prints garbage > DoSomething(sString) > End If > > CopyMemory is kernel32 RtlMoveMemory > > Any advice is greatly appreciated, > Thanks
From: Brian Muth on 2 Jun 2008 19:31 Across process boundaries, Karl?
From: Karl E. Peterson on 2 Jun 2008 19:38 Brian Muth wrote: > Across process boundaries, Karl? D'oh! I missed the part about the 3rd party app loading the DLL, and just saw questionable pointer dereferencing. Good catch. Easiest thing to do in that case, I would think, would be WM_COPYDATA. Especially if he's already worked out finding the hWnd and hooking it. I'm not sure there's a need to ratchet all the way up to DCOM, is there? -- ..NET: It's About Trust! http://vfred.mvps.org
|
Next
|
Last
Pages: 1 2 Prev: Changing network options and joining domain Next: Address of multidimentional array |