我创建了一个 C++ DLL,并在 C# 应用程序中使用它。我应该如何报告错误?
使用异常和throw
我的错误,或者将它们打印在 std::cout 或 std::cerr 或其他什么东西上?如果我在我的 DLL 中发出异常,我的 C# 应用程序能否捕获它?
在这方面最好的做法是什么?
3 回答
这是 C# 使用 PInvoke 调用抛出的方法的示例输出std::exception
。
ex = System.Runtime.InteropServices.SEHException (0x80004005):
External component has thrown an exception.
at ConsoleTester.Program.throw_exception()
at ConsoleTester.Program.Main(String[] args) in ConsoleTester.cs:line 18
注意:在这种情况下 throw_exception() 是公开的本机方法,它调用了一个子方法,但您看不到堆栈跟踪的那部分。对于最深的堆栈帧,您所得到的只是本机边界。
所以,它并不完美,但它确实有效。返回错误代码可能是处理此问题的最标准方法,但如果您是该库的唯一使用者,它可能不会有太大区别。
注意:stdin/stdout 通常是处理错误的最差方法。唯一的例外是编写一个自定义错误处理对象或一组例程,以便在出现问题时应用程序中的所有内容都可以访问,这并不是那么糟糕。(这种接口的输出有时可能是标准输入/标准输出或文件或任何有用的配置)在这里考虑 log4j 或 log4net...
通常,日志记录只是错误处理的一部分。您仍然需要向应用程序的其他部分发出信号,以响应不利条件并(希望)从中恢复。在这里,只有错误代码或异常才能真正正常工作(并且无论如何都要从主程序流中最小化异常)。
不要在stdout
or上打印错误stderr
!您需要以编程方式返回错误,以便 C# 应用程序有机会处理它们。如果主机应用程序是 GUI 应用程序怎么办?
从 C++ DLL 中抛出异常是充满危险的。即使您的应用程序是 C++,也必须使用与 DLL 完全相同的编译器进行编译,就像 @ebyrob 所说的那样。从 C# 调用,我不确定。
最好的做法是返回错误代码。
这实际上取决于错误的强度。我见过的大多数库都会从它们的函数调用中返回成功或失败结果值,您可以在使用它时在代码中手动检查。他们通常提供另一种方法来检索错误消息,以防您想查看它。
为那些你不能没有的真正大的东西保存抛出异常,这将迫使人们使用你的库来修复这些错误(或者至少,看到有一个大问题)。
我不建议在控制台窗口中打印任何内容,这是一个非常缓慢的操作,并且将其放置在其中会迫使使用您的库的任何人都有这种开销,而几乎没有优化选项。如果他们想打印错误消息,他们可以从您的库中检索错误数据并自己打印出来。