抽象包装带有异常的 C 错误处理的最佳方法
Best way to abstract wrapping C error handling with exceptions
有用的 C 库不提供C++绑定的情况并不少见。从C++调用 C 很容易,但除其他问题外,C++项目可能需要异常,而不是数字错误返回值。
是否有任何特定的约定或技巧可以在不在每个函数调用中包含if
和throw
的情况下转换为异常?
我编写了这个解决方案来包装 gphoto2 调用。必须将模板化函数包装在宏中很尴尬(但函数名称对于错误消息很重要;这里的逻辑类似于perror
(。
有没有更好的技术,或者任何开源项目做得特别好?
#include <gphoto2/gphoto2.h>
#include <string>
class Gphoto2Error : public std::exception {
private:
std::string message;
public:
Gphoto2Error(std::string func, int err) {
message = func + ": " + std::string(gp_result_as_string(err));
}
const char *what() const throw() {
return message.c_str();
}
};
template <typename F, typename... Args>
void _gpCall(const char *name, F f, Args... args) {
int ret = f(args...);
if (ret != GP_OK) {
throw Gphoto2Error(name, ret);
}
}
#define gpCall(f, ...) ((_gpCall(#f, ((f)), __VA_ARGS__)))
int main() {
GPContext *ctx = gp_context_new();
Camera *camera;
gpCall(gp_camera_new, &camera);
gpCall(gp_camera_init, camera, ctx);
}
由于有可能(在实践中,通过 __PRETTY_FUNCTION__
或 typeid
(恢复模板参数引用的函数的名称,我会(在 C++17 中(写
template<auto &F,class ...AA>
void gpCall(AA &&...aa) {
if(int ret=f(aa...); ret!=GP_OK)
throw Gphoto2Error(/* … */,ret);
}
int main() {
GPContext *ctx = gp_context_new();
Camera *camera;
gpCall<gp_camera_new>(&camera);
gpCall<gp_camera_init>(camera, ctx);
return 0;
}
获取函数名称的表达式依赖于实现,但在许多情况下,产生可用结果(尽管有额外的文本(的基本方法是添加
#include<typeinfo>
template<auto&> Symbol;
并写typeid(Symbol<F>).name()
.
相关文章:
- 错误处理.将系统错误代码映射到泛型
- 通过错误处理,在C++中可靠地获得用户十六进制输入
- posix_spawn():使用posix_scawn()时的错误处理问题
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 关于 istream 中的错误处理的问题
- 程序使用的 C 库中的错误处理C++
- C++ 错误检查 fstream open() 命令和一般字符串流错误处理
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- Boost进程"系统"功能中的错误处理
- RPN计算器c++错误处理和多个运算符
- 提升精神 x3 错误处理程序与期望
- 构造函数中的错误处理而不会失败
- 当 C++ 中函数参数的输入类型(类)错误时的错误处理
- 关于 ocilib 错误处理的问题,如何使用 ocilib 正确捕获日志错误?
- 我可以使用 std::optional 进行错误处理吗?
- C++ main() 末尾关于错误处理的错误
- 抽象包装带有异常的 C 错误处理的最佳方法
- vwprintf错误处理(ERRNO显示0)
- C++ 使用枚举进行错误处理
- 在 C++ 中创建自己的错误处理机制