我正在将单声道 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");
}
一切都很好。所以问题在于将 long 编组为 DWORD?在这如何解决?