如何在C中映射继承的C ++结构?

时间:2012-05-31 19:06:23

标签: c++ c inheritance typedef

我尝试访问从最初使用结构继承设计的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 ++如何在内部表示继承结构的任何参考?

提前致谢!

4 个答案:

答案 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 ++类可能并不总是有效,因为它将成员和虚方法指针保留在类结构中。