From: santosh.pjb on
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
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
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
Across process boundaries, Karl?



From: Karl E. Peterson on
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