0

背景:我们正在用 C++ 实现一个动态库,它扩展了 C 程序的功能。对于 C 程序中使用的主要结构之一,我们想添加我们自己的库特定字段。目前,当我们需要一个新字段时,我们很好地要求 C 程序的开发人员为我们添加一个字段,但最终我们会遇到大量的铸造混乱。我想知道我们是否可以改为执行以下操作:

主程序头文件:

#ifdef __cplusplus
extern "C" {
#endif
/* ... */
typedef struct ImportantStruct {
/* Definitions */
} ImportantStruct
/* ... */
#ifdef __cplusplus
}
#endif

我们的头文件:

//...
class ObjectType : public ImportantStruct {
// Our extra fields
}
//...

我想我有两个问题:

1)这甚至合法吗?

2) 当 C 程序尝试使用对象的结构部分时,这会产生什么问题?

4

2 回答 2

1

由于它ImportantStruct是一个 POD 结构(它自动具有标准布局),并且由于 ObjectType 没有其他基本类型,并且如果它没有虚拟方法,它也具有标准布局。因此,它可以用作 C 中的结构。

1)这甚至合法吗?

是的。

2) 当 C 程序尝试使用对象的结构部分时,这会产生什么问题?

如果您的 c 函数不尝试覆盖它,那么您是安全的。你可以像这样覆盖它:

void foo( struct ImportantStruct *s )
{
 memset( s,0, sizeof(*s) );
}

如果是,则取决于重要结构中的内容以及是否有填充字节。

像这样的结构:

typedef struct {
  int a;
  char b;
} ImportantStruct;

制作基类时可能会删除填充字节。

无论如何,我会使用组合,并避免任何类型的问题。但是您必须确保它是第一个成员,并且 ObjectType 具有标准布局。

于 2012-11-08T19:05:35.047 回答
0

派生的方法应该有效,只需注意结果对齐。我不会对“扩展”POD 中的结果大小/偏移量做出假设。一些编译器可能会删除基类的填充。因此派生的 C++ POD 可能与 resp 的大小不同。扩展平面 C 结构。

有关派生对象布局的更多详细信息:c-data-alignment-member-order-inheritance

此外,出于扩展 POD 的目的,您可以使用struct关键字 over class。差别不大,只是结构成员默认是公共的。它也表达了你的 POD 意图(尽管它没有被强制执行)。

于 2012-11-08T22:42:03.213 回答