tags:

views:

53

answers:

0

Hello,

i have a c++ dll that contains a function called DoIt :

int WINAPI DoIt()
{
   SetCallback(pCallbackFunc);

   LPSTR pRet = (LPSTR) LocalAlloc(LPTR, 1024);
   memset(pRet, 0, 1024);

   g_CALLBACK(pRet);

   MessageBoxA(0,(LPSTR)pRet,"response",MB_ICONEXCLAMATION);

   LocalFree(pRet);

   return 1;
}

as you can see, this function sets a callback and then fires it, and then displays the pRet string in a message box. the callback is defined as:

typedef VOID (WINAPI *CALLBACK_ROUTINE)(LPVOID pRet);
CALLBACK_ROUTINE g_CALLBACK;

and so the SetCallback function is just:

int WINAPI SetCallback(LPVOID func)
{
   g_CALLBACK = (CALLBACK_ROUTINE)func;
   return 1;
}

so then when the DoIt function fires the callbacks, the pCallbackFunc is called, and all this does is fill in the pRet param:

VOID WINAPI pCallbackFunc(LPVOID pRet)
{
    sprintf((char*)pRet, "response from c++ dll !");
}

i have exported the DoIt function, and created a VB.NET app that loads the C++ dll (using dllimport), and then calls DoIt. the message box is displayed and everything is fine.

now, i need to remove the pCallbackFunc froom the c++ dll and put it into the VB.NET app. so i exported the SetCallback function and created a delegate in the VB.NEt app:

Public Delegate Sub CALLBACK_ROUTINE(ByVal pRet As IntPtr)

i thought pRet should be an IntPtr but this is probably wrong. then i removed the call to SetCallback in the DoIt function in the dll, and i now call SetCallback from the VB.Net app, passing in the pCallback function:

Dim cb As New CALLBACK_ROUTINE(AddressOf pCallback)
SetCallback(cb)

i made the pCallback function like this:

Private Sub pCallback(ByVal pRet As IntPtr)
    pRet = Marshal.StringToHGlobalAnsi("response from vb.net app !")
End Sub

but now when i run the app, the message box displays an empty string. i think the problem is that i am using an IntPtr as the native LPSTR. i have tried other definitions of the delegate too, with the same results:

Private Sub pCallback(ByRef pRet As String) 
    pRet = "response from vb.net app !"
End Sub

Private Sub pCallback(<MarshalAs(UnmanagedType.LPStr)> ByVal pRet As String) 
    pRet = "response from vb.net app !"
End Sub

so my question is, how do i define the delegate type so that the .Net callback can fill in the 'out' param and pass back to the c++ dll ?

thanks in advance for any help.