今天去OGRE的官方網(wǎng)站看到了1.4.0[Eihort]的release note, 其中有一條說是,此版本支持靜態(tài)庫和動態(tài)庫的編譯,由此引發(fā)了厄的以下遐想。
前提:
ogre中可以在靜態(tài)庫和動態(tài)庫的編譯的是一些較為通用的,具有可替換性的組件,如: 渲染器部分,它基于一個公共接口,實現(xiàn)了具體的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下編譯代碼為兩種形式的細(xì)節(jié)如下:
由于打算以LoadLibrary, FreeLibrary, GetAddressSymbol的方式主動載入動態(tài)庫,所以,大多數(shù)情況下不需要導(dǎo)出類的實例成員,不想留給外部使用的成員函數(shù)只需聲明在protected區(qū).
Y: Yes
N: No
M: Maybe
??????????????????????純虛????????導(dǎo)出成員嗎????????????需要另外的創(chuàng)建函數(shù)嗎?????? 需要外加特別的函數(shù)嗎
靜態(tài)庫:?????? Y?????????????? N?????????????????????????????????? M????????? ??????????????????????????????????? N
動態(tài)庫:???????Y?????????????? N???????????????????????????????????Y?(createRenderer之類)????????????Y (DllMain)
由此歸納出,在Windows下,編譯基于抽象類組件為動態(tài)庫比之編譯為靜態(tài)庫只需加上createRenderer和DllMain函數(shù),同時聲明createRenderer為導(dǎo)出函數(shù)。當(dāng)然連接器的選項就不同了,但是編譯器的選項基本一致。
所以,可以做到,先編譯出靜態(tài)庫的.lib文件,然后要得到對應(yīng)的.dll時,只需另外編譯createRenderer和DllMain,然后使用linker從.lib + createRenderer + DllMain就可作出.dll來。大大節(jié)省獲得.dll的時間。
不過我看到OGRE可是兩種情況下各做一次編譯。
所以在遇到static/dynamic庫取舍不定時,至少自問:
a 什么時候需要把庫做成動態(tài)庫?(此問題上面基本已經(jīng)回答了)
b 什么時候同時需要動態(tài)庫與靜態(tài)庫的支持?(這個望能有熱心人多多指點 :)