2012-07-25 37 views
1

在C#中使用_set_purecall_handler与P/Invoke时遇到问题。在C#中使用P/Invoke注册_set_purecall_handler函数

基本上,这个工程:

(C++)

_set_purecall_handler(MyPureCallHandler); 

void MyPureCallHandler(void) 
{ 
    // gets called 
} 

但这并不:

(C#)

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
private delegate void PureCallHandler(); 

[DllImport("msvcr100.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern IntPtr _set_purecall_handler([MarshalAs(UnmanagedType.FunctionPtr)] PureCallHandler handler); 

_set_purecall_handler(MyPureCallHandler); 

private void MyPureCallHandler() 
{ 
    // *** doesn’t get called *** 
} 

我不知道我的P/Inv oke方法签名是正确的,但是当我调用函数时它不会抛出任何错误(它只是不会在纯虚拟调用错误时触发回调)。

背景

我们有一个数字,用一个C#库,用于捕获异常的应用程序(C++,C++/CLI和C#)的。这注册了各种处理程序(AppDomain.CurrentDomain.UnhandledException,SetUnhandledExceptionFilter等)并捕获大多数异常。

但是,它不会捕获纯虚拟调用错误,因此我们需要注册上述函数。

+0

你百分之百确定你的C#被调用到C运行库的相同实例与调用纯虚函数的C++代码相同吗? – 2012-07-25 12:22:02

+0

大卫,我们已经P/Invoke一些kernel32.dll函数,成功拦截C++中的错误(SetUnhandledExceptionFilter,SetProcessUserModeExceptionPolicy,...)但之前没有导入msvcr100.dll。这不应该是一样的吗? – Dunc 2012-07-25 13:30:48

+0

您可能没有获得与您的本机代码相同的C++运行时。但那很可能是一条红鲱鱼。 – 2012-07-25 13:33:23

回答

1

经过试验和错误,我发现引用msvcr100d.dll(d = debug)而不是msvcr100.dll工作,因为我在调试器下工作。

这里是我的源代码(我不知道这是很好的做法,但我已经成功地在调试/发布模式下测试):

private const string DllName = 
    #if DEBUG 
     "msvcr100d.dll"; 
    #else 
     "msvcr100.dll"; 
    #endif 

public delegate void PureCallHandler(); 

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] 
public static extern PureCallHandler _set_purecall_handler(PureCallHandler handler); 
+0

换句话说,这正如我猜测的那样,您正在链接到不同的运行时实例。如果我是你,我会枚举模块句柄,或者让本地代码给你一个模块句柄,然后链接到GetProcAddress。这样你就可以确保获得正确的运行时实例。 – 2012-07-25 22:43:26

+0

@David谢谢 - RE模块处理,一些链接或代码示例会受到欢迎(当然,我不是第一个接入msvcr100的人吗?) – Dunc 2012-07-26 09:00:19

+0

您能修改实际链接到MSVC运行时的本机C++代码吗? – 2012-07-26 11:47:55

相关问题