【发布时间】:2018-04-29 00:19:47
【问题描述】:
在this 等问题中,只要所有成员的类型相同、顺序相同,并且没有声明虚拟成员,就尽可能解释 C++ 类/结构和 C 结构之间的兼容性。
这是我的问题。我有虚方法,我非常希望在用 C++ 操作结构时保留它们。
让我们来看看这个玩具示例。它是在单个头文件中定义的 C 和 C++ 兼容结构。
mystr.h:
#ifdef __cplusplus
#include <string>
struct mystr_base {
virtual ~mystr_base() {}
virtual std::string toString() = 0;
};
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct mystr
#ifdef __cplusplus
: public mystr_base
#endif
{
const char* data;
#ifdef __cplusplus
std::string toString() {
return std::string(data);
}
#endif
};
#ifdef __cplusplus
}
#endif
这可能不是很漂亮,但可以作为示例。在实际场景中,C 和 C++ 变体可能位于不同的标头中,而 C++ 结构扩展了 POD 结构。无论实施如何,对齐问题仍然存在。
在此示例中,如果编写的 C 程序将 mystr 的实例传递给 C++ 函数,则 vtable 将干扰对齐:
test.h:
#include "mystr.h"
#ifdef __cplusplus
extern "C"
#endif
void mycxxfunc(struct mystr str);
test.cpp:
#include <stdio.h>
#include "test.h"
void mycxxfunc(mystr str) {
printf("mystr: %s\n", str.data);
}
main.c:
#include "test.h"
int main(int argc, char** argv) {
const char* testString = "abc123";
struct mystr str;
str.data = testString;
mycxxfunc(str);
}
$ g++ -c test.cpp && gcc main.c test.o
$ ./a.out
Segmentation fault (core dumped)
(假设这是因为 C++ 函数试图从结构分配内存的末尾读取data)
实现这种 C-C++ 互操作性同时仍保留在 C++ 中使用虚函数的能力的最佳方法是什么?
【问题讨论】:
-
结构在c中没有任何成员函数。
-
@user0042 在 C 中编译时,没有定义成员函数。在 C++ 中拥有一个包含成员函数的 POD 结构是完全有效的,它在 C 中使用时将具有完全相同的内存布局。
-
我建议尝试以这种方式混合 C 和 C++。将它们分开。有一个 C++ 类,它有一个 POD 结构的成员变量。如果需要,将令牌(void*)传递给 C++ 类实例的 API 的 C 端,并在该 C/C++ API 屏障处将其打包(到 void*,或返回到 C++ 类指针) .
-
一般来说,多态类不能与C“等价”兼容,因为C没有等价物。您需要知道这些类是如何编译的。那么您的代码将仅适用于编译器的 ABI。
标签: c++ c virtual-functions memory-layout vptr