【发布时间】:2017-02-17 12:35:02
【问题描述】:
我正在使用 P/Invoke 调用来包装原生 API。对于错误处理,我使用以下方法:
- 从托管代码中获取回调函数。
- 从非托管代码调用此回调函数以指示错误。
- 在回调中抛出异常。
换句话说,流程是这样的:
Managed Method => (P/Invoke) Unmanaged Function => Managed Callback => Throw Exception.
当我测试这个方法时,我可以在第一个托管方法中成功捕获异常。但是,我不能 100% 确定这不会对堆栈或内存泄漏造成任何副作用。
使用这种方法安全吗?如果没有,是否有任何其他方法来指示错误(可能包括堆栈跟踪)而不会使使用 P/Invoke 的 API 混乱?
附:我可以访问本机代码。
【问题讨论】:
-
托管回调的作用是什么?如果存在的唯一原因是引发托管异常,您可能应该考虑编写一个 C++/CLI 互操作程序集,无需托管回调即可。
-
是的,我知道 C++/CLI,但是该项目是使用 P/Invoke 方法开始的,并且需要一些工作来转换现有功能。
-
您可以继续使用您拥有的 P/Invoke,并为新代码使用混合模式互操作程序集。无论如何,这并没有完全回答我提出的问题。
-
它会起作用,异常处理在 Windows 上是统一的,堆栈展开是操作系统的职责。然而,本机代码是否期望您抛出异常是一个悬而未决的问题。不太可能。如果是 C++ 代码,则必须使用 /Eha 进行编译,而不是默认设置。如果它是 C 代码,那么它不知道到底发生了什么 :) 内存泄漏和状态损坏是相当可能的结果,因为它们不会导致即时故障,所以很棘手。彻底测试这一点至关重要,请与此代码的作者交谈以感觉更好。期待一个“不!”
-
谢谢。您的评论和this link 澄清一切。
标签: c# c++ exception callback pinvoke