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

MBy*_*ByD 6 c dll struct shared-libraries

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

  • 这样做是否安全,考虑使用不同的编译器编译,结构对齐或其他我没有想到的事情?
  • 它是否需要为库及其用户使用相同的编译器(和标志)?

几点说明:

  1. 我考虑给用户一个指针并通过库中的函数设置所有结构,但这会使API真的不适合使用.
  2. 这个问题是关于C的,虽然知道c ++是否存在差异会很好.

Ale*_*nze 3

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

  1. 不同的编译器(如不同品牌或不同平台的编译器)通常不理解彼此的对象和库格式。
  2. 您不想使用不同类型(例如,signed 与 unsigned char)、类型大小(例如,long = 32 与 64 位)、对齐和打包以及可能的其他一些东西来编译同一程序的不同部分,所有这些都是允许的由C标准来改变。混合和匹配这些东西通常是一件坏事。

但是,您可能经常使用同一编译器的略有不同版本来编译库和使用它的应用程序。通常情况下,没问题。但有时某些更改会破坏代码。

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

此外,可以通过在结构声明中插入显式填充字节并强制紧密打包(例如通过使用#pragma pack,许多编译器都支持)来缓解结构打包问题。这样,如果字体大小相同,则默认包装是什么并不重要。

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