Re: Use of delegate



Hi Bob,

Thanks for your email.
We did not have the declaration of the unmanaged dll and we did not have
the source code, we did not provide support for a third party dll without
source code to P/Invoke.

In my test code, I try to pass the callback function point without another
structure as the parameter. But the principle should be same.
NOTE:
a.return_text = New String("A", 200)
a.size = Marshal.SizeOf(a)

I create a string with 200 as we declare in the vb.net, if the value is
less than 200, we will get the error.

[.NET code]
Imports System.Runtime.InteropServices
Public Class Form1
Public Structure TRVERSION_PARMS
Dim size As Integer ' REQUIRED Size of structure
End Structure

Public Structure TRVERSION_RESP
Dim size As Integer ' REQUIRED Size of structure
Dim return_code As Integer ' 0 if ( no error, != 0 if ( error
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)> _
Dim return_text() As Char ' Contains error text if return code !=
0
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=11)> _
Dim version() As Char ' DLL version
End Structure

Public RVERSION_PARMS As TRVERSION_PARMS
Public RVERSION_RESP As TRVERSION_RESP
Public Delegate Function MyDelegate(ByRef RVERSION_RESP As
TRVERSION_RESP) As Integer

Public Declare Function fnTestDLL Lib "TestDLL.dll" (ByRef
RVERSION_PARMS As TRVERSION_PARMS, ByRef RVERSION_RESP As TRVERSION_RESP,
ByVal md As MyDelegate) As Integer
Public Declare Function fnTest1 Lib "TestDLL.dll" (ByRef RVERSION_RESP
As TRVERSION_RESP) As Integer
Public Function CallBackTest(ByRef RVERSION_RESP As TRVERSION_RESP) As
Integer
MsgBox(RVERSION_RESP.return_text)
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
RVERSION_PARMS.size = Marshal.SizeOf(RVERSION_PARMS)
RVERSION_RESP.size = Marshal.SizeOf(RVERSION_RESP)
MsgBox(fnTestDLL(RVERSION_PARMS, RVERSION_RESP, AddressOf
CallBackTest).ToString())
If (RVERSION_RESP.return_code <> 0) Then
TextBox1.Text = "RVERSION ERROR: " & RVERSION_RESP.return_text
Else
TextBox1.Text = "RVERSION: " & RVERSION_RESP.version
End If
End Sub
Dim a As TRVERSION_RESP
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
a.return_text = New String("A", 200)
a.size = Marshal.SizeOf(a)
fnTest1(a)
End Sub
End Class


[C++ Test dll]

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

// This class is exported from the TestDLL.dll
class TESTDLL_API CTestDLL {
public:
CTestDLL(void);
// TODO: add your methods here.
};

#define REQUEST_DECLINED -2

typedef struct rversion_parms_set_1 RVERSION_PARMS;
typedef struct rversion_resp_set_1 RVERSION_RESP;

#pragma pack(1)

struct rversion_parms_set_1
{
int size; /* REQUIRED Size of structure */
};

struct rversion_resp_set_1
{
int size; /* REQUIRED Size of structure */
int return_code; /* = 0 if no error, != 0 if error */
char return_text[200]; /* Contains error text if return code != 0 */
char version[11]; /* DLL version */
};


#pragma pack()
typedef int (__stdcall *pfnTest)(RVERSION_RESP* pt);

extern TESTDLL_API int nTestDLL;

extern "C" TESTDLL_API int fnTestDLL(RVERSION_PARMS *rversion_parms,
RVERSION_RESP *rversion_resp,pfnTest pfn);
extern "C" TESTDLL_API int fnTest1(RVERSION_RESP* pt);



BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

// This is an example of an exported variable
TESTDLL_API int nTestDLL=0;
pfnTest p;
// This is an example of an exported function.
TESTDLL_API int fnTestDLL(RVERSION_PARMS *rversion_parms, RVERSION_RESP
*rversion_resp,pfnTest pfn)
{
rversion_resp->return_code = 0;
strcpy(rversion_resp->return_text,"Hello");
strcpy(rversion_resp->version,"World");
p= pfn;
return 42;
}

TESTDLL_API int fnTest1(RVERSION_RESP* pt)
{
(*p)(pt);
return 1;
}
// This is the constructor of a class that has been exported.
// see TestDLL.h for the class definition
CTestDLL::CTestDLL()
{
return;
}


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

.