我的问题与这些相似,但似乎并不完全相关:
How to force inclusion of an object file in a static library when linking into executable?
Forcing symbol export with MSVC
我得到的是这样的:
struct thingy;
struct container
{
static container& instance(); // singleton
int register_thingy(thingy*);
};
struct thingy
{
virtual ~thingy() {}
virtual int id() const = 0;
};
//template trick to force registration.
template < typename Derived >
struct registered_thingy : thingy
{
registered_thingy() : my_id(my_static_id) {}
int id() const { return my_id; }
private:
int my_id;
static int my_static_id;
}
template < typename Derived >
int registered_thingy<Derived>::my_static_id =
container::instance().register_thingy(new Derived);
现在,在concrete_thingy.cpp
文件中我有:
struct my_concrete_thingy : registered_thingy<my_concrete_thingy>
{
my_concrete_thingy() {} // registered_thingy's constructor not called otherwise
};
当然,上面的内容完全没用,但这里有抽象的真实行为。
当在作为整体编译的应用程序中使用时,这非常有效。现在的问题是,到目前为止,我还无法在库中填充collection
背后的行为时使用这种技术。换句话说,我有一个包含thingys.lib
的{{1}}文件,但是当链接到可执行文件时,注册不会发生。 <{1}}最终存在且工作正常,但它是空的。
现在,这是一个STATIC库,而不是DLL。这可能会稍微改变这个问题,而上述链接中所说的技术似乎并不适用。当然是关于函数的,我不知道如何将它应用于这些C ++结构。
我尝试在concrete_thingy.cpp
中使用collection
方法和以下三行(当然是单独的),但没有一种方法有效:
#pragma comment
如果concrete_thingy.cpp
在可执行文件而不是库中,则一切正常。
那么,这是我的问题:
1)我可以做我想做的事情吗?我猜是的,但我只是不知道如何。
2)如果有可能,我将如何获得MSVC ++ 2010?
3)如果可能,我怎么能以便携的方式做到这一点?
简而言之,我要做的就是创建一个创建抽象实现的抽象工厂。它对这些实现一无所知,这些实现是使用全局初始化技巧注册的。这应该都在一个可以由应用程序链接的静态库中,这些实现应该可以通过该工厂获得。除了他们自己以外,没有人知道这些实现,因此正常的链接导致它们和它们的注册全局消失。
这不完全是我要做的,但它足够接近。
编辑:============================================= =======
看起来这种行为是“按设计”。 MS认识到造成副作用的物体的构造无论是否使用都会发生,他们使用标准中的漏洞,允许它们不包括不使用任何物品的翻译单位:\
https://connect.microsoft.com/feedback/viewfeedback.aspx?FeedbackID=244410&wa=wsignin1.0&siteid=210
/ OPT:NOREF选项在这种情况下显然不会做任何事情。
答案 0 :(得分:5)
嗯,另一个回答好的尝试,但最终没有结果。我将使用改装技巧,但其余的似乎是一个红色的鲱鱼;它是有道理的,因为有问题的模板实际上并没有在其他任何地方使用,所以它没有明确实例化的事实不应该有所作为...全局的声明仍然发生在A翻译单元中,它有副作用......我不认为标准允许它被优化掉。
关于标准的不幸一点,不说是否需要包括翻译单元是最终的问题。我认为C ++ 0x正在对此做些什么,但也许不是......无论如何,MS根本不会包含单元,因为它不会将全局最终包含在可执行文件中,因此没有其他废话发生。
我决定做什么,当然还有许多其他方法,就是创建一个文件'tag'变量。然后将该标签分配给可全局访问的功能(它可以分配或分配,或者参考被优化掉)。然后必须从可执行文件中调用该函数。
我决定这样做,因为其余的仍然和以往一样。如果我只是编写一个手动注册类型的注册函数,我最终不会最终改变行为。另外,我可以通过这种方式做其他事情......我只需要确保任何可能属于这个fucktardery分类的东西都有一个标签,并且可以访问该标签。
我会写一堆辅助宏来使这种情况变得无痛。
答案 1 :(得分:1)
有链接器选项/ OPT:REF和/ OPT:NOREF,通过链接器 - &gt; optimization-&gt;引用访问。
答案 2 :(得分:0)
经过大量的尝试和丑陋的破解之后,我最终使我的库变得动态(共享)。解决了问题
答案 3 :(得分:0)
快速浏览LINK.exe的文档指向/WHOLEARCHIVE
选项:
/ WHOLEARCHIVE选项强制链接器包括来自指定静态库的每个目标文件。[...]默认情况下,只有在链接器导出由其他对象文件引用的符号时,链接器才将对象文件包括在链接输出中。可执行文件。