我有一个看起来像这样的小数据隐藏模块:
/** mydata.h */
struct _mystruct_t;
typedef struct _mystruct_t mystruct;
mystruct *newMystruct();
void freeMystruct( mystruct** p );
/** mydata.c */
#include "mydata.h"
struct _mystruct_t {
int64_t data1;
int16_t data2;
int16_t data3;
};
// ... related definitions ... //
在大多数情况下,这就是我想要的;虽然简单,但结构有严格的一致性要求,我真的不想提供对数据成员的访问。
问题是,在客户端代码中,我想将该结构包含在另一个我想在堆栈上分配的结构中。现在我正在努力释放一些客户端代码中的 mystruct*
。因为 a) mystruct 非常小,我真的不认为它会很快变大,并且 b) 如果我更改 mystruct,客户端代码必须重新编译不是问题,我想公开 mystruct 的大小(即在标题中)。
我考虑过的两种可能性:
/** mydata.h */
typedef struct {
// SERIOUSLY DON'T ACCESS THESE MEMBERS
int64_t data1;
int16_t data2;
int16_t data3;
} mystruct;
我认为这里的缺点不言自明。
或
/** mydata.h */
#define SIZEOF_MYSTRUCT (sizeof(int64_t)+sizeof(int16_t)+sizeof(int16_t))
// everything else same as before...
/** mydata.c */
// same as before...
_Static_assert (SIZEOF_MYSTRUCT == sizeof(mystruct), "SIZEOF_MYSTRUCT is incorrect")
当然,这似乎不理想,因为我必须手动更新这个值,而且我不知道结构的对齐是否/如何实际导致它不正确(我在写这个问题时想到了静态断言,它部分解决了这个问题)。
其中之一是首选吗?或者更好的是,是否有一些聪明的技巧可以在 header 中提供实际的结构定义,同时以某种方式隐藏访问成员的能力?
最佳答案
您可以创建不同的 .h
文件分发给最终用户,该文件将定义您的 secret 结构,就像字节数组一样(您可以不要在没有加密/校验和的情况下隐藏数据,而不仅仅是说“这里有一些字节”):
typedef struct {
unsigned char data[12];
} your_struct;
您只需确保所有编译器和选项的两个结构都相同,因此使用 __declspec(align())
(对于 VC)在你的库代码中,例如:
// Client side
__declspec(align(32)) typedef struct {
int64_t data1;
int16_t data2;
int16_t data3;
} mystruct;
防止结构长度为 16B 而不是通常预期的 12B。或者只使用 /Zp
编译器选项。
关于c - 私有(private)定义结构的公共(public) sizeof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26181708/