我可以使用' bool '类型或不透明指针指向导出到c的c++函数中的类吗?
Can I use `bool` type or opaque pointers to classes in a c++ function exported to c?
我正在编写一个库的API。库本身将在c++
中编写,但API将使用extern "C"
导出,以获得最佳的跨语言兼容性(稍后我将从C#
, C++
,可能C
和其他一些版本中使用此API)。显然,API不能包括整个类或其他c++
特定的功能(如抛出异常),但我的问题是:
- 可以在导出的API中使用
bool
类型吗?毕竟,它是一个POD。 - 我可以使用不透明的指针类吗?如果是这样,我该如何在头文件中声明它们,以便头文件可以从
C
代码中使用?
Bool应该没问题,ABI和语言设计者对这些事情很小心(例如,来自c++的complex<double>
和来自C的complex double
被明确地设计为兼容)。类可以通过前向声明变成不透明的指针。
#ifdef __cplusplus
class MyClass;
#else
#include <stdbool.h>
typedef struct MyClass MyClass;
extern "C" {
#endif
bool IsActivated(MyClass *p, int x);
#ifndef __cplusplus
}
#endif
请注意,如果设置了各种编译器标志或属性,我已经看到了ABI兼容性问题——例如,如果启用了结构打包,在使用GCC 4.2的C和c++中bool
的大小是不同的。
- 我可以在导出API中使用bool类型吗?毕竟,它是一个POD。 bool是c++特有的类型,如果你在头文件中使用它,它将无法在C中编译。此外,标准没有指定bool将如何实现,因此最好依赖于从int到bool的标准转换
- 我可以使用不透明的指针类吗? 我不知道你在这里不想达到什么目的。普遍接受的方法是将对象的生命周期封装在c++库中,并提供一组C函数来操作该对象。注意,即使你以某种方式允许通过指针访问你的类,你也会被命名混淆和调用约定 所困扰。
我最终进行了测试。以下是测试程序:
test_cpp.cpp:
#include "test.h"
class C {
int a;
public:
C() : a(42) {}
int getA() { return a; }
void setA(int v) { a=v; }
};
int get7(bool b) { return b ? 7 : 3; }
C c;
C* getC() { return &c; }
int getA(C* t) { return t->getA(); }
void setA(C* t, int v) { return t->setA(v); }
test_c.c:
#include <stdio.h>
#include "test.h"
int main()
{
C* c = getC();
printf("%dn", getA(c));
setA(c, 10);
printf("%dn", getA(c));
printf("%dn%dn%dn%dn", get7(0), get7(1), get7(2), get7(-1));
return 0;
}
test.h:
#ifdef __cplusplus
extern "C" {
#else
#define bool _Bool
#endif
struct C;
typedef struct C C;
int get7(bool b);
C* getC();
int getA(C* t);
void setA(C* t, int v);
#ifdef __cplusplus
}
#endif
在windows上使用mingw64 gcc-4.9.0编译
gcc -c test_c.c
g++ test_cpp.cpp test_c.o
编译并正确运行。兴趣点:
-
g++
完全没有问题,C
被声明为struct
,后来被定义为class
- c++
bool
和c
_Bool可以互换工作
我用MS编译器(VS2012)试过了,除了一个我无法解释的小细节外,它的工作原理是一样的:在头文件中,我不得不改变
int get7(bool b);
int get7(bool);
让它编译。如果有人能解释一下,我很乐意理解。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗