我觉得这个问题可能有一个简单的解决方案,这对我来说并不明显 - 我有一个配置类,用于存储从ini文件加载的各种配置选项等。在我的应用程序中,我有一个库和客户端,以及2个配置 - 将库构建为DLL并使客户端动态链接,或将它们作为单个二进制构建在一起。那么如何在库和客户端中使用/使用我的配置对象呢?如果我在两者中都包含配置类定义,我认为它会因重新定义而给我提供链接错误。如何设计一个配置工具既可以静态链接也可以动态链接?
0
A
回答
0
如果我在两者中都包含配置类定义,我认为它会因重新定义而给我提供链接错误。
不,它不会。 Windows DLL不尊重一个定义规则。基本上,在Windows中,ODR在模块边界处停止,即ODR在内内可执行,而在内但不在它们之间。这是不是一件好事是不相关的,就是这样。所以,你可以在DLL和可执行文件中包含你的配置类的定义。但是,将会有两个独立的单例实例(因为我认为它是单例类,正如配置类通常那样),每个模块都有一个实例。从这个意义上讲,它不会是一个真正的单身人士,至少,不是跨模块。
如果你想要一个真正的模块单身人士,你将不得不做更多的工作。您有两种选择:主从或合并(或“菊花链”)。
第一个选项是指定一个模块(例如,可执行文件)作为实例化(并保留)单例对象的模块,然后将指向该实例的指针传递给所有“从”模块,然后通过一个通用接口使用它(因此两个模块对于配置类都有相同的声明,但只有一个模块创建它并将其传递给其他模块)。这将是这个样子:
在头文件 “config_class.h”:
class ConfigClass {
// a bunch of declarations...
public:
static ConfigClass& getInstance(); // the access-point for the singleton.
};
#ifdef MY_LIB_NOW_BUILDING_MASTER
extern "C" __declspec(dllimport) void setConfigClassInstance(ConfigClass* pobj);
#else
extern "C" __declspec(dllexport) void setConfigClassInstance(ConfigClass* pobj);
#endif
在cpp文件 “config_class.cpp”:
#include "config_class.h"
// a bunch of definitions for the config_class member functions.
#ifdef MY_LIB_NOW_BUILDING_MASTER
ConfigClass& ConfigClass::getInstance() {
static ConfigClass instance(/* */);
return instance;
};
#else
static ConfigClass* masterInstance;
void setConfigClassInstance(ConfigClass* pobj) {
masterInstance = pobj;
};
ConfigClass& ConfigClass::getInstance() {
return *masterInstance;
};
#endif
,其中,在上述例如,您可以从主模块(很可能是主可执行文件)中调用setConfigClassInstance来为DLL设置配置对象,但要确保DLL在静态初始化(加载)期间不需要配置类。
第二个选择是合并或菊花链你的单身人士。在这种情况下,每个模块创建自己的单例实例,然后使用与上面类似的方案,将指针传递给彼此的实例,从而将它们合并为一个实例(交叉链接),或者将它们链接在一起(例如,像循环链表或环形列表),并将呼叫分派给相应的实例。
我认为对于您的应用程序,第一个选项可能是最简单的。
N.B .:在非Windows环境下,情况完全不同,以上都不适用。
相关问题
- 1. g ++不能静态链接libmongcxx(r3.0.2)但动态链接可以工作
- 2. 动态链接到静态链接?
- 3. import =动态链接? &include =静态链接?
- 4. SEO:可以动态生成链接吗?
- 5. 创建一个可以弱链接的静态库
- 6. 如何配置NetBeans以静态链接MinGW C++库?
- 7. Angular的深层链接 - 动态链接vs静态链接
- 8. 静态链接一个dylib
- 9. cmake如何部分静态链接,部分动态链接?
- 10. 将动态库链接到一个静态库(又名预链接动态库)
- 11. 静态链接glibc,但动态使用GCC动态链接glibc
- 12. 如何链接一个本身与动态库链接的静态库?
- 13. 如何配置libxml2的动态链接?
- 14. 静态链接的应用程序是否也可链接到一些动态库?
- 15. 如何使一个div可以链接?
- 16. 如何设置动态链接的branch.io
- 17. 如何静态链接.DLL?
- 18. 如何静态链接libstdC++
- 19. 如何静态链接portaudio?
- 20. 我可以将静态库仅与.a文件链接,且没有.xcodeproj链接?
- 21. 在静态导航上动态设置活动链接
- 22. 如何设置链接以便与动态网段路由
- 23. 我可以将一个框架静态链接到另一个框架吗?
- 24. OpenSSL链接libcrypto.a以静态方式
- 25. 设计 - 静态工具类或接口?
- 26. 静态链接库
- 27. 链接静态stdlib.so
- 28. 静态链接glib2
- 29. gcc静态链接
- 30. 静态链接OpenCV
“如果我在两者中都包含配置类定义,我认为它会因重新定义而给我提供链接错误。”语句是用于静态链接(将dll构建为a。lib),而不是动态的;我相信你用上面提供的解决方案,同样会发生。我相信我可以通过预处理器定义的丰富多彩的使用来解决这个问题,但是如果可能的话,我试图避免使用特定的方法。 – Rollie
@Rollie哦,所以,如果我得到这个权利,让我们说你有:main.cpp(应用程序代码),lib.cpp(库代码)和config.cpp(配置类代码)。其中编译成main.o,lib.o和config.o。然后你建立一个“exe + dll”为“(main.o,config.o)+(lib.o,config.o)”的版本,然后你想把dll变成一个静态库,并且天真地尝试链接(main.o,config.o,lib.o,config.o)并获得ODR错误。解决方案很简单,只是在构建静态版本时不要多次链接配置代码。而已。 –