Marshal.GetFunctionPointerForDelegate上的C#System.NotSupportedException

时间:2018-11-29 09:42:10

标签: c# dll marshalling .net-cf-3.5 notsupportedexception

我有以下情况: 我有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);
  }

您有什么建议吗?我忘了什么吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

ClassB的签名具有通用类型参数<T, U>,以将基于通用int的枚举用于外部通信接口,可以说这些枚举分别命名为RequestItemsResponseItems

在问题分析过程中,代码被注释掉,直到检索到最小的工作示例为止。此后,它已逐步取消注释并经过测试-仍然有效,但是在添加了通用类型参数<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>
{
  //..
}

谢谢您的帮助。