首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >库的头文件中的结构定义和编译差异

库的头文件中的结构定义和编译差异
EN

Stack Overflow用户
提问于 2011-12-18 04:49:01
回答 2查看 1.4K关注 0票数 7

我有一个代码被编译成一个库(dll、静态库等等)。我希望这个库的用户使用一些结构来传递一些数据作为库函数的参数。我考虑在API头文件中声明结构。

考虑到使用不同编译器进行编译,在结构对齐或其他我没有想过的事情上,

  • 这样做安全吗?
  • 是否需要对库及其用户使用相同的编译器(和标志)?

很少有人注意到:

  1. I考虑给用户一个指针,并通过库中的函数设置所有的结构,但是这将使API真的很难使用。
  2. 这个问题是关于C的,不过很高兴知道c++.

是否有区别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-18 05:27:56

如果它是一个常规/静态库,则应该使用相同的编译器编译库和应用程序。有几个原因我可以想到:

  1. 不同的编译器(如不同品牌或不同平台的编译器)通常不理解彼此的对象和库格式。
  2. 您不希望使用不同类型(例如签名和无符号字符)、类型大小(例如long = 32 vs64位)、对齐和打包以及其他一些东西编译同一程序的不同部分,所有这些都是C标准允许的。混合和匹配这些东西通常是一件坏事。--

但是,您可能经常使用同一个编译器的不同版本来编译库和使用它的应用程序。通常情况下,没事的。不过,有时也会有一些变化破坏了代码。

您可以在该头文件(声明为static inline)中实现一些“初始化”函数,以确保类型、类型大小、对齐和打包与编译库所期望的相同。使用此库的应用程序必须在使用库的任何其他部分之前调用此函数。如果情况与预期不同,则该函数必须失败并导致程序终止,可能需要对故障进行一些良好的文本描述。这并不能完全解决有一些不兼容的编译器的问题,但它可以防止沉默和神秘的故障。有些东西可以使用预处理器的#if#ifdef指令进行检查,并使用#error造成编译错误。

此外,可以通过在结构声明中插入显式填充字节并强制进行紧密填充(例如使用#pragma pack,这是许多编译器支持的)来解决结构填充问题。这样,如果类型大小相同,那么默认的打包方式就无关紧要了。

您也可以将同样的应用程序应用于DLL,但您确实应该期望调用应用程序是用不同的编译器编译的,而不依赖于编译器是相同的。

票数 3
EN

Stack Overflow用户

发布于 2011-12-18 05:06:41

所有的Windows都像疯了一样抛出结构,所以很明显,这是每天都要做的事情,而且很有效。当然,这并不意味着您所关心的问题是无效的:)我建议使您的结构的字段具有显式宽度类型(int32_t等),并可能显式地指定在任何编译器上的填充都会中断,即

代码语言:javascript
复制
#if defined(_MSC_VER)
#pragma pack(0)
#elif defined ... handle gcc
#else
FAIL // fail compilation on unsupported platform
#endif
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8549890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档