我有以下情况: 我有2个使用事件与C#应用程序通信的c ++ DLL文件。 C#应用程序将Setup()方法中的函数指针传递给两个文件,这些文件以后可以使用此函数指针引发事件。 该应用程序是为 Windows CE 8 和目标框架 Windows Embedded Compact V3.9(.NET CF 3.9)编写的。
每个DLL通信都包装在包含Setup()方法的单个类和包含所有DLL方法的NativeMethods子类中。这两个DLL文件都有一个ItemChanged
事件。
示例代码:
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);
}
除了DllImport参考之外,这两个类均使用了此代码段。
我的问题是,在成功传递classA.Setup()
方法之后,我在Marshal.GetFunctionPointerForDelegate
中的ClassB.Setup()
方法调用中收到System.NotSupportedException。
MSDN文档没有帮助,并且在通过Internet进行爬网时没有发现更多文档。这就是为什么我来这里。
我观察到,当为另一个“测试”委托调用Marshal.GetFunctionPointer
方法时,不会发生该异常,但仍会抛出在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);
}
您有什么建议吗?我忘了什么吗?
谢谢。
答案 0 :(得分:0)
ClassB的签名具有通用类型参数<T, U>
,以将基于通用int的枚举用于外部通信接口,可以说这些枚举分别命名为RequestItems
和ResponseItems
。
在问题分析过程中,代码被注释掉,直到检索到最小的工作示例为止。此后,它已逐步取消注释并经过测试-仍然有效,但是在添加了通用类型参数<T, U>
之后,再次引发了异常。
我没想到类签名会对Marshal.GetFunctionPointerFromDelegate
方法这样的系统方法调用产生如此大的影响。
最小工作示例:
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);
}
}
不起作用的示例-添加:
public ClassB<T, U>
{
//..
}
谢谢您的帮助。