Re: Howto use callback functions with a C DLL
- From: Jef Driesen <jefdriesen@xxxxxxxxxxxxxxxxxxx>
- Date: Wed, 23 Jul 2008 10:52:23 +0200
Jef Driesen wrote:
I have a C DLL that I want to use from a C# project. The C header file contains these declarations:
typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);
void myfunction (callback_t callback, void *userdata);
How do I translate this to C#?
I tried with:
delegate void callback_t (Byte[] data, UInt32 size, IntPtr userdata);
[DllImport("mydll.dll")]
static extern void myfunction (callback_t callback, IntPtr userdata);
When calling with myfunction (null, IntPtr.Zero) everything works as expected. But once I start passing a callback function, the application crashes with "Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
void test (Byte[] data, UInt32 size, IntPtr userdata)
{
// Nothing here
}
callback_t callback = new callback_t (test);
myfunction (callback, IntPtr.Zero);
I tried changing the data parameter from a byte array to an IntPtr, but that seems to make no difference. What am I doing wrong? All other functions (without a callback function parameter) work perfect.
I think C# is somehow messing up the stack of my C DLL. If I export this very simple function in my DLL (declared as extern "C" to avoid name mangling):
typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);
void
myfunction (callback_t callback, void *userdata)
{
unsigned char data[] = {'a', 'b', 'c', 0x00};
printf ("pointer=%p\n", data);
for (unsigned int i = 0; i < 5; ++i) {
printf ("iteration %u\n", i);
if (callback)
callback (NULL, sizeof (data), userdata);
printf ("pointer=%p\n", data);
}
}
And in C#, I use this code:
delegate void callback_t (IntPtr data, UInt32 size, IntPtr userdata);
[DllImport("mydll.dll")]
static extern void myfunction (callback_t callback, IntPtr userdata);
static void test (IntPtr data, UInt32 size, IntPtr userdata)
{
// Nothing here
}
Now, if I call the DLL functon in my main function with the following arguments:
myfunction1 (new callback_t (test), IntPtr.Zero);
I get this output:
pointer=0012F5F0
iteration 0
pointer=0012F5FC
iteration 1
pointer=0012F608
iteration 2
pointer=0012F614
iteration 3
pointer=0012F620
iteration 4
pointer=0012F62C
As you can see, the "data" pointer is increased by 12 bytes after each invocation of the callback function, even if this pointer was never passed to the callback function at all. If I pass "null" for the callback function, the pointer remains the same. If I do the same experiment in a C project, the pointer remains the same, just as it should be. What am I doing wrong?
.
- Follow-Ups:
- Re: Howto use callback functions with a C DLL
- From: Jef Driesen
- Re: Howto use callback functions with a C DLL
- References:
- Howto use callback functions with a C DLL
- From: Jef Driesen
- Howto use callback functions with a C DLL
- Prev by Date: Re: Drop a link to Outlook message
- Next by Date: Re: What classes are suitable for working with XML?
- Previous by thread: Re: Howto use callback functions with a C DLL
- Next by thread: Re: Howto use callback functions with a C DLL
- Index(es):
Relevant Pages
|