1

我尝试访问从最初设计为具有结构继承的 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

4 回答 4

3

POD 的 C++11 规则(什么是聚合和 POD 以及它们如何/为什么特别?指定 不允许将具体的基类与数据成员混合,但实际上对于大多数编译器来说,只有一个 POD 基类相当于将该类封装为第一个成员。

尝试指定封装基本结构的 C 结构:

typedef struct _Struct1
{
    Base base;
    int valueCount;
} Struct1;

请注意,如果 C++ 类不是 POD(例如具有虚拟方法),这将不起作用。

于 2012-05-31T19:18:26.103 回答
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
于 2012-05-31T19:15:04.227 回答
1

调查的一种可能性是您定义的结构是正确的,但编译器使用的对齐方式不匹配。看:

http://en.wikipedia.org/wiki/Data_structure_alignment

通常您可以使用编译器开关或#pragma 指令设置对齐方式。您必须阅读编译器文档才能了解这一点。如果您无法联系 C++ 代码的作者,您可能必须使用调试器查看您收到的原始内存,以计算出结构中不同值之间的对齐/填充是什么。

如果一个程序是为 64 位机器编译的,而另一个程序是为 32 位机器编译的,就会出现这种问题。或者它可能取决于不同的编译器实现。

于 2012-05-31T19:25:57.920 回答
0

您可以尝试在用于将来自 C++ 的值输出到 C 的 C++ 库上使用包装层,而不是直接使用来自 C++ 端的值。如果额外层的开销不会很大,那可能会起作用。

转换 C++ 类可能并不总是有效,因为它将成员和虚拟方法指针保留在类结构中。

于 2012-05-31T19:14:54.370 回答