我应该如何处理基于C++的dll中的错误

How should I deal with errors in my C++ based dll?

本文关键字:C++ dll 错误 何处理 处理 我应该      更新时间:2023-10-16

我已经创建了一个C++DLL,并且正在C#应用程序中使用它。我应该如何报告错误?

使用异常和throw我的错误,或者将它们打印在std::coutstd::cerr上,或者其他什么?如果我在DLL中发出异常,我的C#应用程序能捕捉到它吗?在这方面的最佳行动方案是什么?

下面是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通常是处理错误的最糟糕方法。例外的是,编写一个自定义错误处理对象或一组例程并没有那么糟糕,当出现问题时,应用程序中的所有东西都可以访问这些对象或例程。(这种接口的输出有时可能是stdin/stdout或文件或其他配置有用的东西)请考虑这里的log4j或log4net。。。

通常,日志记录只是错误处理的一部分。您仍然需要向应用程序的其他部分发出信号,以应对不利条件,并(希望)从中恢复过来。在这里,只有错误代码或异常才能真正正常工作(无论如何,主程序流中的异常都要最小化)。

不要在stdoutstderr上打印错误!您需要以编程方式返回错误,以便C#应用程序有机会处理它们。如果主机应用程序是GUI应用程序,该怎么办?

从C++DLL抛出异常充满了危险。即使你的应用程序是C++,它也必须用与DLL完全相同的编译器编译,就像@ebyrob说的那样。从C#调用,我不确定。

最好的做法是返回错误代码。

这实际上取决于错误的强度。我见过的大多数库都会从它们的函数调用中返回一个成功或失败的结果值,当你使用它时,你可以在代码中手动检查它。它们通常提供另一种方法,只在你想看到错误消息时检索它。

将抛出异常保存到那些你无法继续的真正重要的东西上,这将迫使使用你的库的人修复这些错误(或者至少,看到有一个大问题)。

我不建议在控制台窗口中打印任何内容,这是一个非常缓慢的操作,并且在那里打印会迫使任何使用库的人都有这样的开销,而几乎没有优化的选择。如果他们想打印错误消息,他们可以从库中检索错误数据并自己打印出来。