库上的静态变量初始化

时间:2011-03-05 06:28:47

标签: c++ static-libraries static-linking

我正在处理一个将添加类型的工厂,但是,如果该类没有在执行的.exe中明确地进行了详细信息(编译时),则该类型不会添加到工厂中。这是因为静态调用是如何不进行的。有没有人对如何解决这个问题有任何建议?下面是我放入lib的五个非常小的文件,然后一个.exe将调用这个lib。如果有任何关于如何使其工作的建议,或者可能是更好的设计模式,请告诉我。这基本上就是我要找的东西

1)可以接收类型的工厂

2)自动注册进入类.cpp文件,任何和所有注册码都应该在.cpp类中(对于下面的例子,RandomClass.cpp),而不是其他文件。

BaseClass.h:http://codepad.org/zGRZvIZf

RandomClass.h:http://codepad.org/rqIZ1atp

RandomClass.cpp:http://codepad.org/WqnQDWQd

TemplateFactory.h:http://codepad.org/94YfusgC

TemplateFactory.cpp:http://codepad.org/Hc2tSfzZ

3 个答案:

答案 0 :(得分:8)

当您与静态库链接时,实际上是从中提取目标文件,这些目标文件提供当前使用但未定义的符号。在您使用的模式中,可能没有由目标文件提供的未定义符号,其中包含触发注册的静态变量。

解决方案:

  • 使用显式注册
  • 以某种方式具有编译单元提供的未定义符号
    • 使用链接器参数将静态变量添加为未定义的符号
    • 有用的东西,但这通常不自然
    • 一个虚拟的,如果由主程序提供它是不自然的,作为链接器参数它主要比使用静态变量的错位名称更容易
  • 使用链接器参数声明必须包含库的所有对象
  • 动态库是完全导入的,因此没有那个问题

答案 1 :(得分:5)

作为一般经验法则,应用程序不包含库中的静态或全局变量,除非它们被应用程序隐式或显式使用。

有几百种不同的方法可以重构。一种方法可以是将静态变量放在函数中,并确保调用该函数。

答案 2 :(得分:1)

为了扩展@AProgrammer的一个优秀建议,这里有一种可移植的方法来保证调用程序将从库中引用至少一个符号。

在库代码中声明一个返回int的全局函数。

int make_sure_compilation_unit_referenced() { return 0; }

然后在库的标题中声明一个通过调用全局函数初始化的static变量:

extern int make_sure_compilation_unit_referenced();
static int never_actually_used = make_sure_compilation_unit_referenced();

包含标题的每个编译单元都有一个静态变量,需要通过调用库中的(无用)函数来初始化。

如果你的库有自己的命名空间封装了两个定义,那么这会变得更加清晰,那么你的库中的虚假函数与其他库之间的名称冲突的可能性就会降低,或者静态变量与其他变量之间的名称冲突的可能性更小。包含标题的编译单元。