在诸如此类的问题中,只要所有成员的类型相同,顺序相同,并且没有声明任何虚拟成员,就尽可能解释 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 将干扰对齐:
测试.h:
#include "mystr.h"
#ifdef __cplusplus
extern "C"
#endif
void mycxxfunc(struct mystr str);
测试.cpp:
#include <stdio.h>
#include "test.h"
void mycxxfunc(mystr str) {
printf("mystr: %s\n", str.data);
}
主.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++ 中使用虚函数的能力的最佳方法是什么?