C代码中的C++异常处理
C++ exception handling in C codes
当我们用C编写程序时,我们可能会调用一些用C++编写但有C接口的库。然后,当我们调用这些库时,可能会发生C++异常。所以我的问题是我们如何处理这种情况。从C++开发人员的角度来看,我对这个问题更感兴趣。假设我正在开发一个C程序将调用的C++库,我是否应该停止使用异常并返回错误代码?另一种情况是,如果我已经有了一个完全开发的使用异常的C++库,我如何才能以只使用错误返回方法的快速方式传输这个库?
您必须捕获C++端的所有异常,并将它们转换为C中适当的错误返回,其中可能包括适当的特定错误代码。这并不意味着你停止使用异常——你仍然可以在C++中使用它们——但你不能将它们公开给C,它们变成了一个实现细节。
一个典型的包装器的结构如下:
// thingy-wrapper.h, typically included from C code:
#ifdef __cplusplus
extern "C" {
#endif
// create a typedef visible to C that doesn't expose the layout of
// the implementation.
typedef void *thingy_t;
// wrapper for std::string Thingy::get_name()
char *thingy_get_name(thingy_t t);
#ifdef __cplusplus
}
#endif
// thingy-wrapper.cpp, implements the wrapper, compiled with C++:
#include <thingy-wrapper.h>
#include <thingy.hpp> // declares Thingy class
char *thingy_get_name(thingy_t t_)
{
try {
Thingy& t = *static_cast<Thingy*>(t_);
std::string name = t.get_name();
return strdup(name.c_str());
}
catch(...) {
return NULL;
}
}
在这个简单的示例中,thingy_get_name
的调用方可以检测到发生了错误,但无法找出错误的详细信息。一个更现实的例子是捕获特定的异常,并在返回NULL之前将last_error
变量设置为错误代码或消息。...
将仅作为最后手段被捕获,并且将last_error
设置为通用UNKNOWN_ERROR
值。用于查询最后一个错误的单独API(如thingy_last_error()
)将可用于更谨慎的thingy_get_name()
调用方。
错误和非错误结果之间的分离使那些不关心错误原因的代码能够简单地检查是否接收到NULL
,同时允许更认真的代码正确地传播或报告错误。如果您的库是多线程的,请确保last_error
使用线程本地存储。
然后,当我们调用这些库时,可能会发生C++异常。所以我的问题是我们如何处理这种情况。
C代码无法处理这种情况。C代码不能处理C++异常。
假设我正在开发一个C程序将调用的C++库,我是否应该停止使用异常并返回错误代码?
没有。如果您希望C++库由C++代码使用,则应该使用本机C++错误处理。这意味着例外。
但是,您向C代码公开的接口不能引发异常。通常,这意味着编写一个适配器层,捕获C++库引发的异常,并将其转换为C代码使用的错误代码。
另一种情况是,如果我已经有了一个完全开发的使用异常的C++库,我如何才能以只使用错误返回方法的快速方式传输这个库?
这里真的没有捷径可走。您必须编写将C++异常转换为C错误代码的适配器。如果您希望库为C和C++使用者公开接口,那么您无论如何都要编写一个适配器。因此,错误处理只是这个适配器需要处理的另一件事。
异常在C中没有被捕获,所以如果你想捕获它们,那么在你的C代码或C++代码中,你必须非常小心地编写包装器。
还要确保在您的C++函数中,您的函数声明为:
extern "C"
您也可以查看如何混合C和C++
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- 使用 stoi 功能进行异常处理
- 子系统中的异常处理:本机
- 与异常处理程序中的操作员<<不匹配
- 数组 C++ 上的异常处理程序
- 异常处理:如果用户输入不是三个特定字符之一
- C++ 异常处理错误输出
- 视觉 std::矢量无异常:警告 C4530:使用了C++异常处理程序,但未启用展开语义.指定 /EHsc
- C++交换机状态异常处理
- 在字符串类上的成员函数和out_of_range异常处理
- 奇怪的消息 (_Base_bitset::_M_do_to_ulong) 从溢出异常处理程序中打印出来
- 执行视觉工作室异常处理模式
- 为什么隐式转换在异常处理中从派生到基?
- C++执行期间的类成员函数错误/异常处理
- C++ 中未处理的异常处理程序
- 用户定义的异常处理
- C :ScopeGuard vs返回支票和异常处理
- 异常处理期间的类型解析