库上的静态变量初始化

发布于 2024-10-20 13:36:29 字数 860 浏览 3 评论 0原文

我正在开发一个工厂,该工厂将添加类型,但是,如果该类未在执行(编译时)的 .exe 中显式启动,则该类型不会添加到工厂中。这是因为没有进行静态调用。有人对如何解决这个问题有任何建议吗?下面是我放入库中的五个非常小的文件,然后 .exe 将调用该库。如果对如何让它发挥作用有任何建议,或者更好的设计模式,请告诉我。这基本上是我正在寻找的

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

I am working on a factory that will have types added to them, however, if the class is not explicitly instiated in the .exe that is exectured (compile-time), then the type is not added to the factory. This is due to the fact that the static call is some how not being made. Does anyone have any suggestions on how to fix this? Below is five very small files that I am putting into a lib, then an .exe will call this lib. If there is any suggestions on how I can get this to work, or maybe a better design pattern, please let me know. Here is basically what I am looking for

1) A factory that can take in types

2) Auto registration to go in the classes .cpp file, any and all registration code should go in the class .cpp (for the example below, RandomClass.cpp) and no other files.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尐偏执 2024-10-27 13:36:29

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

解决方案:

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

When you are linking with a static library, you are in fact extracting from it the object files which provide symbols which are currently used but not defined. In the pattern that you are using, there is probably no undefined symbols provided by the object file which contains the static variable which triggers registration.

Solutions:

  • use explicit registration
  • have somehow an undefined symbol provided by the compilation unit
    • use the linker arguments to add your static variables as a undefined symbols
    • something useful, but this is often not natural
    • a dummy one, well it is not natural if it is provided by the main program, as a linker argument it main be easier than using the mangled name of the static variable
  • use a linker argument stating that all the objects of a library have to be included
  • dynamic libraries are fully imported, thus don't have that problem
嘿看小鸭子会跑 2024-10-27 13:36:29

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

有数百种不同的重构方式。一种方法是将静态变量放置在函数内部,并确保调用该函数。

As a general rule of thumb, an application do not include static or global variables from a library unless they are implicitly or explicitly used by the application.

There are hundred different ways this can be refactored. One method could be to place the static variable inside function, and make sure the function is called.

等待圉鍢 2024-10-27 13:36:29

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

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

int make_sure_compilation_unit_referenced() { return 0; }

然后在库的标头中声明一个静态变量,该变量通过调用全局函数进行初始化:

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

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

如果您的库有自己的命名空间封装了这两个定义,那么这会变得更清晰一些,那么您的库中的虚假函数与其他库之间或静态变量与编译单元中的其他变量之间发生名称冲突的可能性就会较小( s) 包括标题。

To expand on one of @AProgrammer's excellent suggestions, here is a portable way to guarantee the calling program will reference at least one symbol from the library.

In the library code declare a global function that returns an int.

int make_sure_compilation_unit_referenced() { return 0; }

Then in the header for the library declare a static variable that is initialized by calling the global function:

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

Every compilation unit that includes the header will have a static variable that needs to be initialized by calling a (useless) function in the library.

This is made a little cleaner if your library has its own namespace encapsulating both of the definitions, then there's less chance of name collisions between the bogus function in your library with other libraries, or of the static variable with other variables in the compilation unit(s) that include the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文