2017-02-17 69 views
2

我用P/Invoke调用来包装本机API。对于错误处理,我使用以下方法:用P/Invoke提高托管和非托管回调链的异常

  • 从托管代码中获取回调函数。
  • 从非托管代码调用此回调函数以指示错误。
  • 在回调中抛出异常。

换句话说流动是这样的:

Managed Method => (P/Invoke) Unmanaged Function => Managed Callback => Throw Exception.

当我测试此方法我可以成功地捕获该异常在所述第一管理方法。但是,我不能100%确定这不会对堆栈或泄漏内存造成任何副作用。

使用这种方法安全吗?如果没有,是否有任何其他方法来指示错误(可能包括堆栈跟踪)而不使用P/Invoke混淆API?

P.S.我有权访问本机代码。

+0

托管回调的工作是什么?如果存在的唯一原因是引发一个管理异常,那么您应该考虑编写一个C++/CLI互操作程序集,而不需要托管回调。 – IInspectable

+0

是的,我知道C++/CLI,但项目是以P/Invoke方法开始的,它需要一定量的工作来转换现有的功能。 –

+0

您可以继续使用P/Invoke,然后将混合模式互操作程序集用于新代码。无论如何,这并没有完全回答我所问的问题。 – IInspectable

回答

1

简答:是的,它很安全。

在某些条件下:

  • 非托管函数可以处理SEH异常(C++可以,但C不能)
  • 托管函数将所述异常传递到它的调用者,所以它的调用者必须能够理解并处理Managed异常(或将其传递给上层)。

例如,您无法启动新线程并在新线程中调用托管回调,回调抛出的异常肯定会终止您的应用程序。

+0

通过新线程你是指本地线程,托管线程还是两者兼而有之? –

+0

似乎第一个条件还应该包括只有Visual C++支持这一点。 –

+0

C++和C都可以处理SEH异常。两者都不提供标准语言功能。除非编译C++代码并指示编译器变为非标准,并允许'catch(...)'处理SEH异常(编译器开关'/ EHa')。 – IInspectable