我应该如何处理基于C++的dll中的错误
How should I deal with errors in my C++ based dll?
我已经创建了一个C++DLL,并且正在C#应用程序中使用它。我应该如何报告错误?
使用异常和throw
我的错误,或者将它们打印在std::cout
或std::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。。。
通常,日志记录只是错误处理的一部分。您仍然需要向应用程序的其他部分发出信号,以应对不利条件,并(希望)从中恢复过来。在这里,只有错误代码或异常才能真正正常工作(无论如何,主程序流中的异常都要最小化)。
不要在stdout
或stderr
上打印错误!您需要以编程方式返回错误,以便C#应用程序有机会处理它们。如果主机应用程序是GUI应用程序,该怎么办?
从C++DLL抛出异常充满了危险。即使你的应用程序是C++,它也必须用与DLL完全相同的编译器编译,就像@ebyrob说的那样。从C#调用,我不确定。
最好的做法是返回错误代码。
这实际上取决于错误的强度。我见过的大多数库都会从它们的函数调用中返回一个成功或失败的结果值,当你使用它时,你可以在代码中手动检查它。它们通常提供另一种方法,只在你想看到错误消息时检索它。
将抛出异常保存到那些你无法继续的真正重要的东西上,这将迫使使用你的库的人修复这些错误(或者至少,看到有一个大问题)。
我不建议在控制台窗口中打印任何内容,这是一个非常缓慢的操作,并且在那里打印会迫使任何使用库的人都有这样的开销,而几乎没有优化的选择。如果他们想打印错误消息,他们可以从库中检索错误数据并自己打印出来。
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL