现在的位置: 首页 > 综合 > 正文

静态链接库–类工厂的杯具

2013年09月07日 ⁄ 综合 ⁄ 共 1962字 ⁄ 字号 评论关闭

静态链接库--类工厂的杯具
关键字:静态库 全局 变量 不初始化 类工厂 不注册

原文发表于: http://www.hellocpp.net/Articles/Article/730.aspx

 

 

今天又碰到一个极其BT的问题,从想不通到诧异,从诧异到无奈。只想温柔的说一声:靠!
其实这个故事,以前在做Linux的时候就发现过,没有深入研究,今天经不起真相的诱惑,为了故事的连贯性,我从今天的故事开始。

故事的前奏:
我在设计我的字体系统,场景管理的Node系统,Enity系统的时候大量使用了Factory模式,通过一个String的id就可以创建出一个类来。比如
ISceneNode* pActorNode = xSceneNodeManager::singleton()->createInstance(L"xActorNode", m_pSceneGraph);
这是一个非常美好的设计。将来我要扩展的时候,只要写一个xXXXXSceneNodeFactory。并写一个全局的factory对象,在对象构造函数或者用其他方法注册到xSceneNodeManager中。ISceneNode的扩展是0耦合!!这就是我想要的。
这个美化的故事在我一直使用大块头的dll引擎的时候一直都这样美好着。

故事的发展:
前两天我已经顺利把引擎插入到ATL ActiveX控件中,为了进一步减少体积,考虑到我的dll为了避免安装vc运行库的额外开销,都是采用静态链接CRT的模式,所以我决定,将引擎的所有插件代码都编译到static lib中,并将lib链接到ocx中,这样体积能小很多。
经过一番折腾,我终于将ocx编译出来,整个系统只有一个ocx,又是一个美好的故事啊。。。我开始陶醉:从5个dll,7M大小,直线减少到1.3M。很成功。
但是,,,,美化的时光很短暂,我很快发现,我的ocx根本没法运行!!。

故事的高潮:
经过一番调试,我发现,我的Font系统的类工厂,一个都没有注册过。
神奇!!!!
开始我怀疑我的类工厂有问题,将static改成extern ,去掉static。甚至还试过这样的方法:

class xFT2FontFactory  : public IFontFactory
{
    int type();
};

xFT2FontFactory  g_FT2Fct;
const int xFT2FontFactoryInitV = g_FT2Fct.type();

不管用啥方法,我的类工厂就是不肯自动注册。

无语中...
我google了一下。好不容易找到一篇文章,作者显然也碰到跟我类似的问题:
http://www.cppblog.com/kevinlynx/archive/2010/01/17/105885.aspx
当我的引擎编译成静态库的时候,在链接的过程中,vc只链接了那些我用到的符号表。那些模块中的符号表,如果在别的模块里没用到,那么压根就不会代码整合过来

举例:
我的静态库:
xEvol3D_Release_Static.lib (  xFontRender.obj , xFontManager.obj , xFT2Font.obj , xBmpFont.obj )

我将在 xEvol3D_WebControl.ocx中使用 xEvol3D_Release_Static.lib
当然,由于我“优秀的”设计模式,在 xEvol3D_WebControl.ocx 中我显然不会直接去使用xFT2Font.obj和xBmpFont.obj中的对象。但是xFT2Font.obj中的静态变量会自动注册类工厂到xFontManager.obj的类中,然后 xEvol3D_WebControl.ocx 通过xFontManager的接口创建出xFontRender对象来使用。
这个时候,因为 xEvol3D_WebControl.ocx 没有引用到 xFT2Font.obj 的符号,其他模块也没有引用xFT2Font.obj。于是“聪明”的连接器就把我的xFT2Font.obj给扔了。。。

 

无奈的结果:
我找了好多资料,还挨个看了看VC的编译设置,暂时没有发现任何地方可以“Full link all  module in static lib"的选项。极其杯具。
无奈,我只能改成动态链接库。不同的时候,把插件的代码整合到一起。

后记:
1. 测试过我找到的那篇文章的方法,在其他地方强行引用 xFT2Font.obj中的符号,那么这个模块就进来了。代码也对了。但是显然我不会这样做。我这样的类太多。不现实。
2. 想起<Unix编程艺术>里的一个条款:越是花哨的东西越是容易出问题。看来真是报应啊。
3. 从7M减少1.3M也是个幻觉。好多代码都没进去。当然小了。sigh!
4. Linux也有同样的问题。我用gcc的时候,也发现过类似的问题。

 

抱歉!评论已关闭.