今天去OGRE的官方网站看到了1.4.0[Eihort]的release note, 其中有一条说是,此版本支持静态库和动态库的编译,由此引发了厄的以下遐想。

前提:
ogre中可以在静态库和动态库的编译的是一些较为通用的,具有可替换性的组件,如: 渲染器部分,它基于一个公共接口,实现了具体的DirectX和OpenGL的各版本的具体组件.

example:
// in IRenderer.h
class Renderer {
public:
  virtual bool begin(Rect* pArea) =0;
  virtual void end() =0;
};

// in DxRenderer.h
// singleton
class DxRenderer: public Renderer {
public:
  virtual bool begin(Rect* pArea);
  virtual void end();
};

// in OGLRenderer.h
// singleton
class OGLRenderer: public Renderer {
public:
  virtual bool begin(Rect* pArea);
  virtual void end();
};

// user code on dynamic/static library
Renderer* r = createRenderer(Dx9_Version);   // need export when by dynamic library
r->begin(0);
r->end();

在Windows下编译代码为两种形式的细节如下:
由于打算以LoadLibrary, FreeLibrary, GetAddressSymbol的方式主动载入动态库,所以,大多数情况下不需要导出类的实例成员,不想留给外部使用的成员函数只需声明在protected区.

Y: Yes
N: No
M: Maybe

                      纯虚        导出成员吗            需要另外的创建函数吗       需要外加特别的函数吗
静态库:       Y               N                                   M                                              N
动态库:       Y               N                                   Y (createRenderer之类)            Y (DllMain)

由此归纳出,在Windows下,编译基于抽象类组件为动态库比之编译为静态库只需加上createRenderer和DllMain函数,同时声明createRenderer为导出函数。当然连接器的选项就不同了,但是编译器的选项基本一致。

所以,可以做到,先编译出静态库的.lib文件,然后要得到对应的.dll时,只需另外编译createRenderer和DllMain,然后使用linker从.lib + createRenderer + DllMain就可作出.dll来。大大节省获得.dll的时间。

不过我看到OGRE可是两种情况下各做一次编译。

所以在遇到static/dynamic库取舍不定时,至少自问:
a 什么时候需要把库做成动态库?(此问题上面基本已经回答了)
b 什么时候同时需要动态库与静态库的支持?(这个望能有热心人多多指点 :)