【问题标题】:Can you run a function on initialization in c?你可以在c中运行初始化函数吗?
【发布时间】:2010-06-21 02:39:25
【问题描述】:

在程序加载时是否有运行函数的机制或​​技巧?

我正在努力实现的目标......

void foo(void)
{
}

register_function(foo);

但显然 register_function 不会运行。

所以 C++ 中的一个技巧是使用初始化来使函数运行

类似

int throwaway = register_function(foo);

但这在 C 中不起作用。所以我正在寻找一种使用标准 C 的方法(没有特定于平台/编译器的)

【问题讨论】:

  • 因为我想要一个数字 .c 文件,而且我不希望人们必须记住将 register 函数放在 main....

标签: c initialization portability


【解决方案1】:

如果您使用的是 GCC,您可以使用 constructor 函数属性来执行此操作,例如:

#include <stdio.h>

void foo() __attribute__((constructor));

void foo() {
    printf("Hello, world!\n");
}

int main() { return 0; }

但是,在 C 中没有可移植的方式来执行此操作。

不过,如果您不介意弄乱您的构建系统,那么您还有更多选择。例如,您可以:

#define CONSTRUCTOR_METHOD(methodname) /* null definition */

CONSTRUCTOR_METHOD(foo)

现在编写一个构建脚本来搜索 CONSTRUCTOR_METHOD 的实例,并将对它们的一系列调用粘贴到生成的 .c 文件中的函数中。在main()开头调用生成的函数。

【讨论】:

  • 很好,这是我想要的,但我希望有更标准的 C
  • bdonlan 的解决方案不使用 C++。再读一遍;它只是 GCC 特定的。
  • 他改变了答案,它曾经也有一个 C++ 解决方案
  • 构建脚本有点麻烦,因为它是框架的一部分,应该可以无缝集成到您的项目中。我可以做坏事.....我可以制作一个结构(使用宏)并在其中放入一个魔术字符串和一个函数指针,然后在运行时查看内存中的魔术字符串并恢复结构:-)
  • 我认为这将比使用 GCC 构造函数扩展更不便携。此外,误报可能会导致非常难以调试的错误。
【解决方案2】:

标准 C 不支持这样的操作。如果您不希望使用编译器特定的功能来执行此操作,那么您的下一个最佳选择可能是创建一个初始化为 false 的全局静态标志。然后,每当有人调用需要注册函数指针的操作之一时,您就会检查该标志。如果为假,则注册该函数,然后将标志设置为真。随后的调用将不必执行注册。这类似于 OO Singleton 设计模式中使用的惰性实例化。

【讨论】:

    【解决方案3】:

    虽然 gcc 为函数提供了 constructor 属性,但没有标准的方法来执行此操作。

    确保已完成某些预设置的常用方法(除了对编译时值进行简单的变量初始化)是确保所有需要该预设置的函数。换句话说,类似于:

    static int initialized = 0;
    static int x;
    
    int returnX (void) {
        if (!initialized) {
            x = complicatedFunction();
            initialized = 1;
        }
        return x;
    }
    

    这最好在一个单独的库中完成,因为它使您与实现隔离。

    【讨论】:

    • 是的....但是在我的情况下,我想要一个预先设置,其中一个函数将被注册并存储在一个列表中......然后稍后会通过该列表运行注册的函数。目前这意味着每个功能都需要显式添加到某个中心位置。我想找到一个技巧,可以在声明时注册函数
    猜你喜欢
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多