C++ 在静态库中全局初始化类实例

C++ 在静态库中全局初始化类实例,c++,visual-c++,static-libraries,C++,Visual C++,Static Libraries,我正在一个静态库中实现Qt框架的QTextCodec。为了使我的编解码器实现注册到QTextCodec::codeformib(int)和QTextCodec::codeforname(const char*),必须发生以下几件事: 编解码器的实例必须初始化(但不一定要使用) 实例不能被删除或超出范围 这似乎是因为QTextCodec::QTextCodec()使用已知编解码器的字典注册了该实例。可以所以,如果我将一个全局变量添加到我的应用程序(与静态库链接),单元测试就会成功 然而,我更愿

我正在一个静态库中实现Qt框架的
QTextCodec
。为了使我的编解码器实现注册到
QTextCodec::codeformib(int)
QTextCodec::codeforname(const char*)
,必须发生以下几件事:

  • 编解码器的实例必须初始化(但不一定要使用)
  • 实例不能被删除或超出范围
这似乎是因为
QTextCodec::QTextCodec()
使用已知编解码器的字典注册了该实例。可以所以,如果我将一个全局变量添加到我的应用程序(与静态库链接),单元测试就会成功

然而,我更愿意将全局实例放在静态库中,这样链接到全局实例的应用程序就不需要自己动手了但是如果应用程序不引用一个类实例,我想不出如何在静态库中初始化该类实例


除非我在应用程序中引用
x
,否则
QMyTextCodec x
QMyTextCodec*x=new QMyTextCodec
都不会实际初始化类的实例。

您可以通过语句将选项传递给MSVC链接器,并使用该选项强制它链接变量

#pragma comment(linker, "/INCLUDE:variable_name")
如果使用
/OPT:REF
优化标志,这将覆盖删除该变量。为了使
#pragma
语句正常工作,它需要至少出现在链接到静态库的项目的一个翻译单元(源文件)中。这可以通过将其放置在保证包含在项目中的头文件中来实现。您还需要考虑名称修饰,因为
#pragma
不会自动处理它

Init.cpp

QMyTextCodec initvariable;
#include "staticlib/MainHeader.h"
#include "something.h"
...
...
MainHeader.h

#pragma comment(linker, "/INCLUDE:?initvariable@@3VQMyTextCodec@@A")
然后在任何依赖静态库的项目中,只需包含
MainHeader.h

#pragma comment(linker, "/INCLUDE:?initvariable@@3VQMyTextCodec@@A")
ExternalProjectMain.cpp

QMyTextCodec initvariable;
#include "staticlib/MainHeader.h"
#include "something.h"
...
...
注意:如果符号名称不正确,将出现未解决的链接器错误

- 根据GCC文档,您可以使用
\uuuu属性\uuu
关键字实现类似的效果。然而,我手头没有一个GCC安装来测试这个


可以通过语句将选项传递给MSVC链接器,并使用该选项强制链接变量

#pragma comment(linker, "/INCLUDE:variable_name")
如果使用
/OPT:REF
优化标志,这将覆盖删除该变量。为了使
#pragma
语句正常工作,它需要至少出现在链接到静态库的项目的一个翻译单元(源文件)中。这可以通过将其放置在保证包含在项目中的头文件中来实现。您还需要考虑名称修饰,因为
#pragma
不会自动处理它

Init.cpp

QMyTextCodec initvariable;
#include "staticlib/MainHeader.h"
#include "something.h"
...
...
MainHeader.h

#pragma comment(linker, "/INCLUDE:?initvariable@@3VQMyTextCodec@@A")
然后在任何依赖静态库的项目中,只需包含
MainHeader.h

#pragma comment(linker, "/INCLUDE:?initvariable@@3VQMyTextCodec@@A")
ExternalProjectMain.cpp

QMyTextCodec initvariable;
#include "staticlib/MainHeader.h"
#include "something.h"
...
...
注意:如果符号名称不正确,将出现未解决的链接器错误

- 根据GCC文档,您可以使用
\uuuu属性\uuu
关键字实现类似的效果。然而,我手头没有一个GCC安装来测试这个


这是针对特定平台(即VisualC++还是便携式的?)我猜我回到了其他平台的绘图板,但这是一个好的开始。谢谢。不幸的是,您的Q被标记为Virtual-C++并且您没有请求任何其他平台,因此答案的范围很窄。您现在也有了一个针对GCC的解决方案。我还不能测试GCC版本,但不幸的是,#pragma不会导致在应用程序中初始化我静态库中的全局。这是特定于特定的应用程序吗平台(即Visual C++还是便携式)?我猜我已经回到了其他平台的绘图板,但这是个好的开始。谢谢。不幸的是,你的Q被标记为Virtual-C++并且你没有请求任何其他平台,因此答案的范围很窄。你现在也有了一个GCC解决方案。我还不能测试GCC版本,但不幸的是,#pragma不会导致我的静态库中的全局在应用程序中初始化。可能存在重复的副本