mono_delegate_to_ftnptr:函数调用挂起

时间:2012-05-15 06:07:15

标签: mono interop unmanaged managed internal

我将单声道2.10.8嵌入到我的应用程序中,并且在mono_add_internal_call

注册时遇到了一些功能问题

假设我有管理方法:

internal delegate void Win32ServiceHandler(long statusCode);

internal static class Win32Service
{
  [MethodImpl(MethodImplOptions.InternalCall)]
  public static extern void Test(Win32ServiceHandler handler);
}

这是非托管定义:

void icall_TestDelegateCallback(MonoDelegate *ftn) {
  LPHANDLER_FUNCTION f = (LPHANDLER_FUNCTION)mono_delegate_to_ftnptr(ftn);
  f(SERVICE_CONTROL_STOP);
}

和一些要测试的代码:

protected virtual void ServiceHandler(Win32ServiceControl statusCode)
{   
  Console.WriteLine("here");
}

public void MakeTest()
{
  Console.WriteLine("before");
  Win32Service.Test(this.ServiceHandlerInternal);
  Console.WriteLine("after");
}

我从控制台应用程序运行它,当我调用MakeTest()时,输出为:

before
here

应用程序永远不会返回。

实际上它是一个简化的示例。在实际程序中,我需要将函数指针作为回调函数传递给RegisterServiceCtrlHandler,所以像mono_runtime_invoke这样的东西(btw工作正常)等不是我需要的。

问题是调用从MonoDelegate获得的函数指针的正确方法是什么?或者是将其作为回调传递的其他正确方法吗?

我的平台是Windows 7 x64

UPD:

有趣的发现。一旦我将代码更改为:

internal static class Win32Service
{
  [MethodImpl(MethodImplOptions.InternalCall)]
  public static extern void Test(Action handler);
}

typedef VOID (*TESTFTN)();

void icall_TestDelegateCallback(MonoDelegate *ftn) {
  TESTFTN f = (TESTFTN)mono_delegate_to_ftnptr(ftn);
  f();
}

public void MakeTest()
{
  Console.WriteLine("before");
  Win32Service.Test(() => Console.WriteLine("here"));
  Console.WriteLine("after");
}

Everithing很棒。所以问题在于编组长到DWORD?在这方面它如何解决?

1 个答案:

答案 0 :(得分:0)

DWORD是32位整数类型,而C#中的long是64位类型。