[英]How to force a linked library to load using Visual C++ on Windows
I am trying to handle a project with multiple dynamic libraries, in the libraries some global objects are created and registered in a list so that the executable can use them to build other things. 我正在尝试处理具有多个动态库的项目,在库中创建一些全局对象并在列表中注册,以便可执行文件可以使用它们来构建其他内容。 In the executable there's no reference to any function of any library, it just needs the objects, and then it knows what to do.
在可执行文件中,没有任何库的任何函数的引用,它只需要对象,然后它知道该怎么做。 These libraries are intended to work like plugins that are chosen at link time.
这些库旨在像链接时选择的插件一样工作。
Ideally when compiling ExecutableProject
I link LibraryA
, an object of type A
gets created (by some code that's compiled in the library) and ExecutableProject
does things because of it, using functions in LibraryA
. 理想情况下,在编译
ExecutableProject
I链接LibraryA
,会创建A
类型的对象(通过在库中编译的一些代码),并且ExecutableProject
会使用LibraryA
函数来完成它。 If instead I link LibraryB
then an object of type B
gets created and other things happen. 如果相反,我链接
LibraryB
然后创建类型B
的对象,并发生其他事情。
The problem is, since ExecutableProject does not directly use any function or class in the library, the library is not loaded, and objects are never created. 问题是,由于ExecutableProject不直接使用库中的任何函数或类,因此不会加载库,也不会创建对象。
I have found some workarounds: 我找到了一些解决方法:
/INCLUDE:symbol
at link time when compiling ExecutableProject
, where symbol is any symbol exported in LibraryA
or LibraryB
. ExecutableProject
,我可以在链接时使用/INCLUDE:symbol
,其中symbol是在LibraryA
或LibraryB
导出的任何符号。 I don't like this because I have to know the decorated name of a function in the library, which is not always available. __declspec(dllexport) int force_link_A_or_B;
__declspec(dllexport) int force_link_A_or_B;
in LibraryA
and LibraryB
and __declspec(dllimport) extern int force_link_A_or_B;
LibraryA
和LibraryB
和__declspec(dllimport) extern int force_link_A_or_B;
in ExecutableProject
. ExecutableProject
。 I don't like this because if I had more libraries I'd have to add a variable for each of them. ExecutableProject
does not know which libraries will be linked, it still needs to know how many of them can be linked together. ExecutableProject
中的代码不知道将链接哪些库,但它仍然需要知道它们中有多少可以链接在一起。 On Linux, using gcc and ld, it's very easy to solve this problem, all it takes is a simple linker flag -Wl,--no-as-needed
. 在Linux上,使用gcc和ld,很容易解决这个问题,所需要的只是一个简单的链接器标志
-Wl,--no-as-needed
。 Is there any way to do this using Visual Studio? 有没有办法使用Visual Studio? I would be happy if there was something that worked like
/INCLUDE
but used entire libraries instead of symbols and did not need decorated names. 如果有一些像
/INCLUDE
一样的东西但是使用整个库而不是符号并且不需要装饰名称,我会很高兴。
Thanks 谢谢
EDIT: I have been asked to clarify how this design is intended to work. 编辑:我被要求澄清这个设计是如何工作的。 Ideally, when I compile
ExecutableProject
I link LibraryA
or B
and an object is created. 理想情况下,当我编译
ExecutableProject
我链接LibraryA
或B
并创建一个对象。
`ClassA A;`
This is placed outside all functions in a source file that is compiled in LibraryA
. 它位于
LibraryA
编译的源文件中的所有函数之外。 Same thing happens in LibraryB
. 同样的事情发生在
LibraryB
。 The key here is that ClassA
and ClassB
inherit from a BaseClass
that ExecutableProject
knows well. 这里的关键是
ClassA
和ClassB
继承自ExecutableProject
熟悉的BaseClass
。 When the object is created, the BaseClass
constructor is run, and inside it a BaseClass*
pointer pointing to this
(therefore the derived object) is saved, and ExecutableProject
uses that pointer. 创建对象时,将运行
BaseClass
构造函数,并在其中保存指向this
的BaseClass*
指针(因此派生对象),并且ExecutableProject
使用该指针。 It does not need to know anything about the derived classes, because it uses only a BaseClass
pointer, but when it calls virtual functions from it, different functions are executed depending on the actual type of the pointed object. 它不需要知道派生类的任何内容,因为它只使用
BaseClass
指针,但是当它从中调用虚函数时,根据指向对象的实际类型执行不同的函数。 If there were more objects instead that just two alternatives, I would save BaseClass
pointers in a list or a map, and let ExecutableProject
access it. 如果有更多的对象只有两个替代品,我会在列表或地图中保存
BaseClass
指针,并让ExecutableProject
访问它。
Don't try this. 不要试试这个。 The design is fundamentally flawed.
设计存在根本缺陷。
In particular, since you are not making any explicit calls to the DLL, you would rely only on object A
being created via an implicit call to DllMain
. 特别是,由于您没有对DLL进行任何显式调用,因此您将仅依赖于通过对
DllMain
的隐式调用创建的对象A
But under Windows rules, you are barred from doing anything interesting in or from DllMain
, so object A
cannot be very useful. 但是在Windows规则下,你被禁止在
DllMain
做任何有趣的事情,所以对象A
不是很有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.