通过C绑定来公开C 库
Exposing a C++ library via C bindings
是否有任何可用的准则,习惯,最佳实践...如何通过C绑定来公开C 库(作为库的一部分编译)。
目的是不是修改C 类。
假设以下两个C 类
class B {
public:
std::vector<int> list();
std::string toString();
};
class A {
public:
explicit A(size_t size);
B getB();
};
将其视为C API的"最佳"方法是什么?处理指针和实例化对象的功能列表,回调?有没有公认的命名约定的列表?
extern "C" {
A* A_new(size_t size);
void A_delete(A* a);
B* A_getB(A *a);
void B_delete(B* b);
...
}
(注意:要求公认的实践和惯例和/或工具是不是征求意见,而是实际反馈)
我的经验是,要回答的基本问题是c 对象是某种类型的单例,还是在接口的C侧有多个实例。
如果它们是单例,则C接口可以是一组函数,并且所有管理,对象手柄和其他位都保存在接口的C 侧。库的用户不需要任何一种引用特定C 对象的方法。
但是,如果C 对象有多个实例,则必须确定如何处理这些多个对象及其寿命的决定。我看到的主要两种方法是(1)提供一个指向C 对象的指针到接口的C侧,或(2)向C 对象提供一个句柄,并用句柄引用AC 方面的管理区域。
我个人喜欢手柄方法,因为那时现代的C 实践可以用于管理对象的寿命。对象存储在某些C 容器中,该容器具有提供给C接口的唯一手柄或标识符,并且C 侧拥有对象。C侧正在通过C接口对对象上的特定操作。
C接口可能会在映射到单个C 对象方法的唯一函数之间或更通用的函数,该功能通过指定C 对象方法的唯一标识符,将其构成命令标志的内容。
。在第一个替代方案中,C 对象的方法将作为C接口函数公开,在多个实例的情况下,将指向C 对象的指针或对象的句柄。C接口函数,用C 编写,然后使用正确的参数调用实际的C 对象方法。因此,这只是将参数转发到C 对象的C接口函数。
在第二个替代方案中,C 接口函数必须使用查找表或switch
或类似的方法来确定要调用的方法。可以在接口中指定参数,也可以使用可变参数。如果使用了可变参数,则您存在解析参数列表,提交参数然后调用C 对象方法的问题。
另一个考虑因素是命名和名称空间混乱。在C中,有传统的三个字母前缀方法来命名外部命名,尽管在大多数情况下,更多的字符更有意义。
但是,我真正喜欢的方法是拥有一个外部结构,其中是构成接口的C函数的功能指针。通过执行此操作,您可以将结构命名为图书馆有意义的东西,然后您可以随意命名实际功能指针。
实际的C接口函数是源文件中的static
,它仅公开包含函数指针的结构。结构本身是一个全局,当在包含C接口函数的源文件的底部定义时将其初始化。
您提出的问题通常是处理此问题的最佳方法。您的函数可以将指针返回到新分配的对象,一组函数,该功能采用该指针并执行各种操作,还有一个将指针拿到指针并释放内存的功能。
您唯一需要添加的是声明与C:
兼容的类型typedef struct A A;
typedef struct A B;
您不应该在C接口中公开STD类型(B类中的公共成员),因为C ABI未标准化,您可能最终会遇到很难找出的错误当API消费者使用不同的编译器版本时。
例如,在您的代码中,我将重写B如下:
class B {
public:
int* list(); // or write your own implementation for a vector type which you ship with the api
const char* toString();
};
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- C++通过绑定到引用成员而缩短临时变量寿命?
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- C++ sqrat 通过包装器绑定方法
- 如何发送通过绑定到函数/方法创建的函数对象?
- 函数参数绑定通过参考与传递指针传递数组的规则
- 通过类比理解 C++17 中的结构化绑定
- 通过C绑定来公开C 库
- TR1::绑定和通过引用传递,这种行为真的是预期的吗?
- 通过将返回值绑定到const引用,C++性能得到改善
- 通过不明确的转换运算符进行引用绑定
- 如何通过引用将函数绑定到对象
- 无法通过SSL (ldaps://)将示例程序绑定到LDAP服务器
- 如何通过NCurses的c++绑定在屏幕上显示NCursesPanel
- 如何通过pthreads将类成员函数与类的对象绑定以创建线程
- 通过指针绑定类的方法
- 什么最适合编写一次本机库,并通过语言绑定跨多种语言使用它