gpt4 book ai didi

c - 我应该相信调用库初始化函数有利于性能吗?

转载 作者:太空宇宙 更新时间:2023-11-04 08:32:03 24 4
gpt4 key购买 nike

我正在用 C(不是 C++)创建一个库,并且有一个关于什么是常见做法的问题。

此库需要调用 %libname%_Init() 函数,以便其他函数可以执行其适当的职责(否则,必然会发生未定义/意外行为,可能导致崩溃).

如果使用简单的 if (%random_var%) 调用,我可以轻松检查每个函数的顶部,所以我想知道是否有对此的约定。

Ps¹:一个真实的例子是 SDL.h 需要 SDL_Init(/*modules to be initialized */)

Ps²:如果 stackoverflow 不是解决此类问题的地方,我深表歉意

最佳答案

如果您不介意利用 gcc(以及其他可能的)扩展,您可以查看 __attribute__ ((constructor))(参见 here),它保证函数是在 main() 之前调用。这样您就知道您的 init 函数已被调用。

但是,在一般情况下,如果您的库需要初始化,则很可能是它做错了。您可能希望完全避免在库中使用全局变量,这意味着您不想使用这种 init 函数。

作为落入此陷阱的伟大库的示例,请查看 libxml2。它有一个你需要调用的初始化函数来分配内存。为了让任何人都能看到(例如)valgrind 的干净输出,他们需要释放分配的内存,因此他们必须调用 deinit 函数;当然只有一些应用程序会这样做。到目前为止,一切都很好。但是如果另一个库 (libfoo) 也使用 libxml2 会发生什么?他们都调用 init 函数(很棒)。但是如果有人调用 deinit 函数呢?如果 libfoo 不调用它,那么任何使用 libfoo 的东西都会泄漏内存。如果 libfoo 确实调用了它,那么任何使用 libfoo 的东西在使用 libfoo 完成后都不能使用 libxml2。一团糟(作者承认)。

更好的策略是每个用户获取库的上下文(通过一次调用,返回一个指针),它分配一个 struct,其中包含您原本会用作全局变量的内容。这个指针被传递给每个调用。这样您就知道必须调用 init 函数,因为这是获得此类指针的唯一方法。此外,如果每个上下文仅由一个线程使用,您的库几乎是自动线程安全的(显然您需要避免使用任何本身依赖全局变量的函数)。一个例子:

 BarContext context = bar_newcontext();
...
bar_dosomething (context, ...);
...
bar_freecontext (context);

关于c - 我应该相信调用库初始化函数有利于性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27891480/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com