>我正在将单声道 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
(顺便说一句工作正常(等东西不是我需要的。
问题是调用从 MonoDelegate 获得的函数指针的正确方法是什么?还是将其作为回调传递的任何其他正确方法?
我的平台是Windows 7 x64
上级:
有趣的发现。一旦我将代码更改为:
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");
}
一切都很好用。所以问题在于将长编组到 DWORD?这怎么解决呢?
DWORD 是 32 位整数类型,而 C# 中的 long 是 64 位类型。