我尝试访问从最初使用结构继承设计的C ++库接收的C程序数据:
示例:
// C++ data structures
typedef struct _Base
{
public:
int id;
wchar_t* name;
} Base;
typedef struct _Struct1 : Base
{
public:
int valueCount;
} Struct1;
typedef struct _Struct2 : Base
{
public:
int parentID;
int amount;
} Struct2;
我尝试在C中使用以下数据结构进行映射。
typedef struct _Base
{
int id;
wchar_t* name;
} Base;
typedef struct _Struct1
{
// Base struct data
int id;
wchar_t* name;
int valueCount;
} Struct1;
typedef struct _Struct2
{
// Base struct data
int id;
wchar_t* name;
int parentID;
int amount;
} Struct2;
但是打印数据,看起来我的错误值。
我错过了什么,关于C ++如何在内部表示继承结构的任何参考?
提前致谢!
答案 0 :(得分:3)
关于POD的C ++ 11规则(What are Aggregates and PODs and how/why are they special?)指定 不允许将具体基类与数据成员混合,但实际上对大多数编译器来说拥有一个POD基类相当于将该类封装为第一个成员。
尝试指定封装基础结构的C结构:
typedef struct _Struct1
{
Base base;
int valueCount;
} Struct1;
请注意,如果C ++类是非POD(例如,有虚拟方法),这将不起作用。
答案 1 :(得分:2)
您可能会欺骗C编译器生成具有相同C ++类内存布局的结构,并且在许多情况下都可以使用,但这是一个相当不稳定的基础。
便携式方法是编写访问器功能。请务必将其声明为extern "C"
。
头文件的说明性示例(不一定是干净的;在Web表单中编写代码的典型注意事项适用: - )):
#ifdef __cplusplus
// C++ declarations go here
class Foo
{
public:
int bar;
};
// C calling conventions follow
extern "C" {
#else
// Make it so your C code can work with Foo* as an incomplete/not-dereferencable
// type.
typedef void Foo;
#endif
// Declare this in a C++ source file to return fooptr->bar
int foo_get_bar(Foo *fooptr);
#ifdef __cplusplus
} // extern "C"
#endif
答案 2 :(得分:1)
调查的一种可能性是,您定义的结构是正确的,但编译器使用的结构不匹配。参见:
http://en.wikipedia.org/wiki/Data_structure_alignment
通常可以使用编译器开关或#pragma指令设置对齐方式。您必须阅读编译器文档以了解相关信息。如果您无法联系C ++代码的作者,您可能必须使用调试器来查看您正在接收的原始内存,以确定结构中不同值之间的对齐/填充。
如果为64位计算机编译一个程序而为32位计算机编译另一个程序,则会出现此类问题。或者它可以归结为不同的编译器实现。
答案 3 :(得分:0)
您可以尝试在正在使用的C ++库上使用包装层将输出来自C ++的值输出到C,而不是直接使用来自C ++端的内容。如果额外层的开销不大,那可能会有效。
转换C ++类可能并不总是有效,因为它将成员和虚方法指针保留在类结构中。