[英]Using C++ struct with virtual members (i.e. non-POD) in C
在的问题,如本 ,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结构。 无论实施如何,对齐问题仍然存在。
在这个例子中,如果编写了一个将mystr
实例mystr
给C ++函数的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 ++互操作性的最佳方法是什么?
我不建议你用#ifdefs
混乱你的头文件。
如果您想同时保留某种虚拟化和C兼容性,那么在这种情况下您应该做的第一件事是:
一个想法如下。
头文件:
struct MyStrImpl;
struct MyStr {
MyStrImpl * impl;
};
extern "C" MyReturnType myFunction(MyStr myStr);
在.cpp
文件中的实现:
struct MyCppString {
virtual ...
};
#ifdef __cplusplus
struct MyStrImpl : public MyCppString {
};
#else
struct MyStrImpl {
};
#endif
MyStr::MyStr() : impl{new MyStrImpl{}} {
}
这样,您就可以使用C和C ++中的类型。
好处:
#ifdef
。 缺点:
您不能同时在头文件中同时使用C兼容类型和虚函数,而不会使用#ifdef
使其混乱,这是我不建议的,因为如果您需要重构代码会很不方便。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.