我应该如何处理C++;基于动态链接库? 我创建了一个C++ DLL,我在C语言应用程序中使用它。我应该如何报告错误? 使用异常并抛出我的错误,或者将它们打印在std::cout或std::cerr上,或者其他什么东西上?如果我在DLL中发出异常,我的C#应用程序是否能够捕获它? 在这方面,什么是最好的行动方案?

我应该如何处理C++;基于动态链接库? 我创建了一个C++ DLL,我在C语言应用程序中使用它。我应该如何报告错误? 使用异常并抛出我的错误,或者将它们打印在std::cout或std::cerr上,或者其他什么东西上?如果我在DLL中发出异常,我的C#应用程序是否能够捕获它? 在这方面,什么是最好的行动方案?,c#,c++,dll,C#,C++,Dll,不要在stdout或stderr上打印错误!您需要以编程方式返回错误,以便C#应用程序有机会处理它们。如果主机应用程序是GUI应用程序怎么办 从C++ DLL中抛出异常充满了危险。即使你的应用程序是C++,它也必须编译成与DLL完全相同的编译器,比如@ EBYROB说。从C#打来的电话,我不确定 最好的做法是返回错误代码。不要在stdout或stderr上打印错误!您需要以编程方式返回错误,以便C#应用程序有机会处理它们。如果主机应用程序是GUI应用程序怎么办 从C++ DLL中抛出异常充满了危

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

<>从C++ DLL中抛出异常充满了危险。即使你的应用程序是C++,它也必须编译成与DLL完全相同的编译器,比如@ EBYROB说。从C#打来的电话,我不确定


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

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

<>从C++ DLL中抛出异常充满了危险。即使你的应用程序是C++,它也必须编译成与DLL完全相同的编译器,比如@ EBYROB说。从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


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

下面是一个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


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

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

保存抛出异常,对于那些您无法继续使用的非常大的东西,这将迫使使用您的库的人修复这些错误(或者至少,看到有一个大问题)


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

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

保存抛出异常,对于那些您无法继续使用的非常大的东西,这将迫使使用您的库的人修复这些错误(或者至少,看到有一个大问题)

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

您所说的“C++dll”是什么意思?您是否使用
extern
或类似工具公开本机类?通常,DLL应该是“C DLL”(可能用C++编写)或“COM DLL”或“托管程序集”。创建一个直接暴露本地C++对象的DLL通常是个坏主意,因为它很难与没有生成它的编译器版本相链接。