【发布时间】:2018-11-29 09:42:10
【问题描述】:
我有以下情况: 我有 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);
}
这个 sn-p 在两个类中都使用了,除了 DllImport 引用之外没有任何变化。
我的问题是,在成功传递classA.Setup() 方法后,我在ClassB.Setup() 中的Marshal.GetFunctionPointerForDelegate 方法调用上收到System.NotSupportedException。
MSDN 文档没有帮助,我在互联网上爬网时没有找到更多文档。这就是我来这里的原因。
我观察到在为另一个“测试”委托调用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);
}
你有什么建议吗?我是不是忘记了什么?
谢谢。
【问题讨论】:
-
sn-ps 中缺少对回答这个问题很重要的 一个 细节。委托的返回类型。咨询我的水晶球:将 bool 更改为 int。
-
感谢 Hans Passant 指出这一点;返回类型是无效的。我会在描述中更正它。
-
Hmya,你问这个问题已经晚了十年。考虑根本不使用 GetFunctionPointerForDelegate。没有必要,您可以简单地将方法声明为 void Configure(EventDelegate eventCallback)。请注意,您仍然必须将委托对象存储在变量中,以确保它不会被垃圾回收。
-
谢谢汉斯,我会试试这个,稍后再回来查看更新。
标签: c# dll marshalling .net-cf-3.5 notsupportedexception