By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,144 Members | 849 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,144 IT Pros & Developers. It's quick & easy.

Passing delegates in structure to C dll

P: n/a
I am a starter in C# ...

I will present my problem :

I am wrapping a C dll in C#. The C dll exports a function which takes a
structure MYSTRUCT holding 2 function pointers(callback functions).

struct MYSTRUCT
{
ontest1 t1;
ontest2 t2
};
where ontest1 and ontest2 are two function pointers.

In C# dll, I have declared this structure as

[StructLayout(LayoutKind.Sequential)]
public struct MYSTRUCT
{
[MarshalAs(UnmanagedType.FunctionPtr)]
ontest1 t1;
[MarshalAs(UnmanagedType.FunctionPtr)]
ontest2 t2
}

where ontest1 and ontest2 are two delegates.
//Importing the C dll function "MyFunctions"

[DllImport("mydll.dll")]
IntPtr MyFunctions(IntPtr myStruct);

//The .NET function wrapping the above function :

IntPtr MyFunctions1(ref MYSTRUCT mystruct)
{
//Converts MYSTRUCT to pointer
GCHandle callbackHandle = GCHandle.Alloc
(mystruct ,GCHandleType.Pinned);

IntPtr mystructptr = callbackHandle.AddrOfPinnedObject();

//Calls the imported C dll function
IntPtr handle = MyFunctions(mystructptr);

return handle;
}
The address in the delegates in MYSTRUCT are stored inside the C dll..
and the same functions are invoked whenever an event occurs. That is
the unmanaged code calls the managed code asynchronously.

The call to the C dll is working fine.. but whenever an event occurs
the registered function is not getting involked..
Do I have to add/remove anything more to the code?

Any help will be appreciated...

regards
Renjini

Jun 30 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"renjini" <re**************@gmail.com> wrote:
I am a starter in C# ...
I am in no way an expert in P/Invoke, but there is something obviously
wrong with the code below:
[StructLayout(LayoutKind.Sequential)]
public struct MYSTRUCT
{
[MarshalAs(UnmanagedType.FunctionPtr)]
ontest1 t1;
[MarshalAs(UnmanagedType.FunctionPtr)]
ontest2 t2
}

where ontest1 and ontest2 are two delegates.

//Importing the C dll function "MyFunctions"

[DllImport("mydll.dll")]
IntPtr MyFunctions(IntPtr myStruct);
I think you need to use 'ref MYSTRUCT myStruct' or 'out MYSTRUCT
myStruct', because otherwise using IntPtr directly will hide the actual
type of the arguments from .NET, and it won't be able to marshal the
calls (it needs to generate stub methods to adjust for managed / native
boundary). Delegates are not the same as unmanaged function pointers
(they are at least 8 bytes in size, for one thing), and that's another
reason why P/Invoke needs to see into this structure.
//Converts MYSTRUCT to pointer
GCHandle callbackHandle = GCHandle.Alloc
(mystruct ,GCHandleType.Pinned);


The above call boxes the struct (in order to convert it from a ValueType
- i.e. a C# struct - to the reference type 'object' aka System.Object),
and returns a pinned handle to this copy of the struct on the heap.
Thus, any modifications that MyFunctions does to the struct will be
modifying a copy of the structure.

But: there is more. A boxed struct on the heap is more than just the
struct: it also contains a reference to the method table etc. of the
class (analogous to vtable in C++). So, your pointer may not be a
pointer to MYSTRUCT.t1, but in fact may point to a .CLR method-table
pointer.

I think you should use 'ref mystruct', and let .NET P/Invoke create the
pinned handle automatically.

Alternatively, use C++/CLI or Managed C++.

-- Barry

--
http://barrkel.blogspot.com/
Jun 30 '06 #2

P: n/a
thanks Barry .. I ll try and let you know the result...

Jul 1 '06 #3

P: n/a

Hi Barry,

I forgot to mention the point that this .NET dll (which wraps the
C dll) and the application using it as well, has to be deployed in a
mobile device that is using Compact Framework (2.0)

I had tried the way you suggested earlier, but I am getting an
exception "NotSupportedException".
It was because of this that I had pinned the structure, and I changed
the signature of the imported function from ref MYSTRUCT to IntPtr.

I have come to a dead end because of this...

-renjini

Jul 1 '06 #4

P: n/a
"renjini" <re**************@gmail.comwrote:
I forgot to mention the point that this .NET dll (which wraps the
C dll) and the application using it as well, has to be deployed in a
mobile device that is using Compact Framework (2.0)

I had tried the way you suggested earlier, but I am getting an
exception "NotSupportedException".
It was because of this that I had pinned the structure, and I changed
the signature of the imported function from ref MYSTRUCT to IntPtr.

I have come to a dead end because of this...
The only other thing I can suggest is, have you tried writing a test
case in C++/CLI?

-- Barry

--
http://barrkel.blogspot.com/
Jul 2 '06 #5

P: n/a
Sorry , no I havent tried till now..

Jul 3 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.