Reputation: 387
I have the following situation: I have 2 c++ DLL files communicating with a C# application using events. The C# application passes function pointers within a Setup() method to both files which may later raise an event using this function pointer. The application is written for Windows CE 8 and the target framework Windows Embedded Compact V3.9 (.NET CF 3.9).
Each DLL communication is wrapped within a single class containing a Setup() method and a NativeMethods sub-class containing all DLL methods. Both DLL files have an ItemChanged
event.
Sample Code:
private delegate void EventDelegate(int item, int value);
private EventDelegate _eventCallback;
private IntPtr _eventCallbackAddress;
private void OnEvent(int item, int value)
{
Debug.WriteLine("Item: " + item + ", value: " + value);
}
private void Setup()
{
_eventCallback = new EventDelegate(OnEvent);
_eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback); // NotSupportedException
try
{
NativeMethods.Configure(_eventCallbackAddress);
}
catch (Exception ex)
{
Debug.WriteLine(this, ex.Message);
}
}
private static class NativeMethods
{
[DllImport("A.dll", EntryPoint = "Configure", CallingConvention = CallingConvention.WinApi)]
public static extern void Configure(IntPtr eventCallback);
}
This snippet is used in both classes without changes except DllImport reference.
My problem is that after successfully passing classA.Setup()
method, I receive a System.NotSupportedException on Marshal.GetFunctionPointerForDelegate
method invocation in ClassB.Setup()
.
MSDN documentation did not help and I found no further documentation while crawling through the internet. Which is why I came here.
I've observed that the exception does not occur when calling Marshal.GetFunctionPointer
method for another "test" delegate, but it is still thrown on Marshal.GetFunctionPointer(_eventCallback)
private Delegate testDelegate;
private void Foo() { };
private void Setup()
{
testDelegate = new Action(Foo);
IntPtr p = Marshal.GetFunctionPointerForDelegate(testDelegate);
_eventCallback = new EventDelegate(OnEvent);
_eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback); // NotSupportedException
try
{
NativeMethods.Configure(_eventCallbackAddress);
}
catch (Exception ex)
{
Debug.WriteLine(this, ex.Message);
}
Do you have any suggestions? Did I forget something?
Thank you.
Upvotes: 0
Views: 542
Reputation: 387
The signature of ClassB had generic type parameters <T, U>
to utilize generic int-based enumerations for an external communication interface, lets say these enumerations are named RequestItems
and ResponseItems
.
During problem analysis, the code was commented out until a working minimal example has been retrieved. After that it was step-wise uncommented and tested - it still worked, but after adding back the generic type parameters <T, U>
, the exception was thrown again.
I did not expect that the class signature can have such an impact to system method invocations like Marshal.GetFunctionPointerFromDelegate
method.
Working minimal example:
public ClassA
{
private delegate void EventDelegate(int item, int value);
private EventDelegate _eventCallback;
private IntPtr _eventCallbackAddress;
private void OnEvent(int item, int value)
{
Debug.WriteLine("Item: " + item + ", value: " + value);
}
private void Setup()
{
_eventCallback = new EventDelegate(OnEvent);
_eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback);
try
{
NativeMethods.Configure(_eventCallbackAddress);
}
catch (Exception ex)
{
Debug.WriteLine(this, ex.Message);
}
}
private static class NativeMethods
{
[DllImport("A.dll", EntryPoint = "Configure", CallingConvention = CallingConvention.WinApi)]
public static extern void Configure(IntPtr eventCallback);
}
}
Not working example - add :
public ClassB<T, U>
{
//..
}
Thank you for your help.
Upvotes: 0