【问题标题】:Use NULL pointer in C shared library在 C 共享库中使用 NULL 指针
【发布时间】:2020-11-09 22:48:12
【问题描述】:

我正在创建一个 C 共享库。我向具有以下声明的用户提供了一个函数:

int getResults(Elements** el)

其中 Elements 是用户提供的结构数组,然后函数用值填充该数组。每次计算出的最终元素个数都不一样,取决于其他函数中的参数,所以必须有办法告知用户元素个数。

我没有一个单独的函数来返回元素的数量,我实现的方式是用户可以使用 NULL 参数调用这个相同的函数来获取现有元素的数量:

int n = getResults(NULL);

分配所需的内存,然后传递数组指针。所以,在函数内部,我检查:

if(el == NULL)
{
    return numEl;
}
else
{
    // Proceed to fill the structs.
    
    // If all good, return 0
    return 0; 
}

现在,我担心的是,这种方法会失败吗?

我已经读过,NULL 并不一定意味着一个特定的数字,即 0。那么,例如,如果用户使用另一个编译器、标准编译器或将其与 C++ 集成来链接库,是否可以保证这个等式始终为真?

【问题讨论】:

  • 任何方法都有失败的可能。
  • 从哲学上讲?
  • 总是说。
  • 这是 ABI 的问题(没有它,您基本上根本无法链接库)。例如,System V ABI 明确指定 “空指针(对于所有类型)的值为零”.
  • 如果两个模块/语言足够兼容,能够跨越边界传递非空指针,并且就指向的内存的含义达成一致,那么它们应该足够兼容以达成一致NULL的定义。

标签: c++ c pointers dll


【解决方案1】:

这种方法会失败吗?

这可能会被误解。

除此之外,我认为 API 没有问题。

我已经读过,NULL 并不一定意味着一个特定的数字,即 0。那么,例如,如果用户使用另一个编译器、标准编译器或将其与 C++ 集成来链接库,是否可以保证这个等式始终为真?

Null 为空,不管它代表什么数字。语言标准中没有太多关于跨语言/编译器障碍的兼容性的直接保证。这不仅限于 null 的表示,而是语言实现的许多方面。通常,编译器努力与同一系统上的其他编译器兼容。如果一个编译器与另一个编译器兼容,那么就没有问题。如果不兼容,那么更改 API 不太可能解决不兼容问题。

使用共享库依赖于用于生成组件的编译器的兼容性。如果你不能依赖编译器相互兼容,那么你就不能跨越它们的边界进行函数调用。相反,您将不得不依赖序列化通信,例如通过套接字。


我会考虑编译器在其他方面兼容的情况,除了它们对 null 的定义是高度理论化的。但是有一种方法可以设计 API,使其不依赖于 null 的定义,以避免在这种假想情况下出现问题:让 AP​​I 的用户提供库应该接受为“null”的指针值。

【讨论】:

  • 所以,换句话说,“也许”。
  • @RobertHarvey 附带“如果缺乏保证是一个问题,不要混合编译器/语言”的隐含附录。
  • 那么,你会建议我放弃这种方法吗?
  • 是的,但是引用您的回答“语言标准中没有太多关于跨语言/编译器障碍的兼容性的直接保证。”。如果编译器 1 用 X 表示 NULL,编译器 2 用 Y 表示 NULL,那么这将失败。
  • @Mr.Y 那么,你能相信编译器是否兼容吗?我的建议取决于您对此的回答。
猜你喜欢
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多