青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

轉自http://www.imyaker.com/blog/article.asp?id=34
插件系統-選擇GetProcAddress還是Interfaces(譯)
原文:
Plugin System – an alternative to GetProcAddress and interfaces
下載文件 代碼下載
[介紹]
有很多文章描述如何實現一個簡單的插件框架,比如后面的鏈接[1]和[2]。通常有兩種方法
(1) 插件實現一組標準的(并且通常是小的)函數(方法)。宿主(host)知道這些函數的名字,并且可以通過使用GetProcAddress函數獲得這些函 數的地址。這并不合適,隨著函數數量的增長,維護變得越來越困難。你必須手動通過函數名綁定函數,這樣你就不得不做很多工作。
(2)GetProcAddress所返回的函數被用來傳遞接口指針(Interface Pointer)給插件或者從插件里獲取接口指針。剩下的宿主和插件的通信通過接口完成。下面是一個例子

我 們將使用一個簡單的例子。宿主程序是一個圖片查看器。它實現了一個插件框架來增加對不同圖片格式的支持(在這個例子中就是24-bit的BMP圖象和24 -bit的TGA(Targa)圖象)。插件將被實現為DLLs并且將有.imp的擴展名以便和普通dll文件區分開來了.注意,盡管如此,可是這篇文章 是關于插件的,而不是關于圖象解解析器的。這里所提供的解析器非常基礎并且只是用來說明的。

[使用接口的方法]
接口是所有函數都是公共的并且純虛的基類,并且沒有沒有數據成員。比如
程序代碼 程序代碼
// IImageParser is the interface that all image parsers
// must implement
class IImageParser
{
    public:
    // parses the image file and reads it into a HBITMAP
    virtual HBITMAP ParseFile( const char *fname )=0;
    // returns true if the file type is supported
    virtual bool SupportsType( const char *type ) const=0;
};

實際的圖象解析器必須繼承自接口類并且實現純虛函數。BMP文件解析器可能是這個樣子。
程序代碼 程序代碼
// CBMPParser implements the IImageParser interface
class CBMPParser: public IImageParser
{
    public:
    virtual HBITMAP ParseFile( const char *fname );
    virtual bool SupportsType( const char *type ) const;

private:
    HBITMAP CreateBitmap( int width, int height, void **data );
};

static CBMPParser g_BMPParser;

// The host calls this function to get access to the
// image parser
extern "C" __declspec(dllexport) IImageParser *GetParser( void )
{
    return &g_BMPParser;
}

宿主將使用LoadLibrary函數來載入BmpParser.imp,然后使用GetProcAddress("GetParser")來得到GetParser函數的地址,然后調用它得到IImageParser類的指針。
宿主將保存了注冊了的解析器的鄰接表(list),它把GetParser函數返回的指針附加到那個鄰接表上去。
當宿主需要解析一個bmp文件的時候,它將調用每個解析器的SupportType(".BMP")。如果返回類型是true,宿主將調用那個解析器并且使用完整文件名調用待解析文件,并將繪制HBITMAP句柄指向的位圖。

基類并不真的必須是純接口。在技術上這里的限制是所有的成員必須可以通過對象指針訪問。所以你可以有:
- 純虛成員函數(它們能通過虛表被間接訪問)
- 數據成員(它們可以通過對象的指針直接訪問)
- 內聯成員函數(技術上它們不能通過指針訪問,但是它們的代碼又一次在插件里實例化。
這樣就剩下了非內聯和靜態成員函數。插件無法從宿主訪問這樣的函數,宿主也不能對插件進行這樣的操作。不幸的是在一個大型系統之中,這樣的函數要占據代碼的大部分。

例如所有的圖象解析器需要CreateFunction函數。有必要在基類里聲明它并且在宿主端實現。否則每個插件都將有一份這個函數的拷貝。
這個方法的另一個限制是你不能由宿主端暴露任何全局成員或者全局函數給插件端。
我們怎么改進呢?

[把宿主分成Dll和Exe]
讓 我們看一下USER32模塊,它有兩個部分 - user32.dll 和 user32.lib。真正的代碼和數據在dll中,lib僅僅提供調用dll函數的占位函數。最好的事情在于它是自動發生的。當你鏈接到 user32.lib你就自動地獲得訪問user32.dll函數的權利。(這里翻譯的不好)
MFC 實現得更進一步 - 它暴露你能直接使用和繼承的整個類。它們沒有我們在上面討論的純虛接口類的限制。
我 們也能做同樣的事情。任何你想提供給插件的函數(我私下覺得原文functionality這個詞用得不好)都能放在一個單獨的Dll里。使用 /IMPLIB 鏈接器選項來創建相應的 LIB 文件。插件能與那個靜態庫鏈接,并且所有導出函數都能提供給它們。你能按你喜歡的方式把代碼分成Dll 和 Exe。極限情況下,像在代碼里演示的那樣,Exe 工程里僅僅含有一行WinMain函數,它僅僅用來啟動Dll。
任何你想要導出的全局數據,函數,類,或者成員函數必須被標記為 __declspec(dllexport) 在編譯插件時。一個常用的技巧是使用宏
程序代碼 程序代碼

#ifdef COMPILE_HOST
// when the host is compiling
#define HOSTAPI __declspec(dllexport)
#else
// when the plugins are compiling
#define HOSTAPI __declspec(dllimport)
#endif

添加宏COMPILE_HOST的定義到Dll工程里,但是不加到插件工程里。

在宿主Dll端:
程序代碼 程序代碼

// CImageParser is the base class that all image parsers
// must inherit
class CImageParser
{
public:
    // adds the parser to the parsers list
    HOSTAPI CImageParser( void );
    // parses the image file and reads it into a HBITMAP
    virtual HBITMAP ParseFile( const char *fname )=0;
    // returns true if the file type is supported
    virtual bool SupportsType( const char *type ) const=0;

protected:
    HOSTAPI HBITMAP CreateBitmap( int width, int height,
    void **data );
};

現在基類并不僅僅限于一個接口。我們能增加更多基本功能。CreateBitmap函數將被所有解析器共享。
這次不再是宿主調用一個函數來獲取解析器并且將它添加到鄰接表中,這個功能被CImageParser的構造函數取代。當解析器對象被創建,它的構造函數將自動更新鄰接表。宿主不必再使用GetProcAddress函數來看看什么解析器在Dll里。

在插件端:
程序代碼 程序代碼
// CBMPParser inherits from CImageParser
class CBMPParser: public CImageParser
{
public:
    virtual HBITMAP ParseFile( const char *fname );
    virtual bool SupportsType( const char *type ) const;
};

static CBMPParser g_BMPParser;

當g_BMPParser被創建是它的構造函數 CBMPParser() 將被調用。那個構造函數(在插件端實現)將調用基類的構造函數CImageParser() (在宿主端實現)。那是可能的因為構造函數被標記為HOSTAPI。
等等,還可以變得更好

[把宿主Dll和Exe連接起來]
(這一部分暫時沒翻譯)

[鏈接]
[1] Plug-In framework using DLLs by Mohit Khanna
[2] ATL COM Based Addin / Plugin Framework With Dynamic Toolbars and Menus by thomas_tom99

PS.我想,Interface方法,是在第一種方法之上加入了一個間接層。
我現在到沒有太強的感覺非內聯函數和靜態函數會成為這樣一個大型系統的主要部分,Interface的派生類中的非內聯函數應該只被純虛接口函數調用,不然就是接口設計有問題了。

posts - 94, comments - 138, trackbacks - 0, articles - 94

Copyright © RichardHe

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产美女高潮久久白浆| 欧美日韩在线观看一区二区| 欧美性做爰毛片| 美日韩精品免费| 午夜精品剧场| 久久久999成人| 免费久久久一本精品久久区| 裸体丰满少妇做受久久99精品 | 性欧美激情精品| 午夜一区不卡| 久久天天综合| 欧美日韩美女在线| 国产欧美一区二区视频| 激情久久久久久| 亚洲精品字幕| 欧美一区二区在线| 欧美成人免费小视频| 亚洲精品永久免费精品| 亚洲欧美成人精品| 免费看亚洲片| 国产精品一区在线观看你懂的| 国内精品免费午夜毛片| 亚洲欧洲精品一区二区| 亚洲一区在线直播| 久久一区中文字幕| 一本色道久久88综合亚洲精品ⅰ| 欧美一区免费视频| 欧美日韩国产系列| 伊人久久av导航| 亚洲女性喷水在线观看一区| 六月婷婷久久| 亚洲视频成人| 蜜臀99久久精品久久久久久软件| 国产精品mm| 亚洲欧洲三级电影| 久久久无码精品亚洲日韩按摩| 亚洲精品一区二区三区av| 久久精品视频在线看| 国产精品久久久久久久久久久久久久 | 亚洲一区二区三区777| 久久久亚洲精品一区二区三区 | 国产日韩欧美夫妻视频在线观看| 国产欧美亚洲视频| 在线精品视频在线观看高清| 亚洲欧美国产日韩天堂区| 欧美激情亚洲视频| 久久成人人人人精品欧| 国产精品久久久久久久久婷婷| 亚洲激情校园春色| 免费欧美视频| 久久精品国产久精国产爱| 国产精品视频精品视频| 亚洲午夜国产一区99re久久| 最新成人av网站| 久热精品在线| 在线成人激情视频| 蜜乳av另类精品一区二区| 午夜日韩av| 国产伦一区二区三区色一情| 亚洲一级高清| 在线视频欧美日韩精品| 欧美日韩日本国产亚洲在线| 欧美深夜福利| 一个色综合导航| 亚洲人午夜精品免费| 欧美激情中文不卡| 亚洲精品免费看| 亚洲精品美女久久久久| 欧美裸体一区二区三区| 日韩午夜免费视频| 一本色道久久综合亚洲精品婷婷| 欧美三级乱人伦电影| 亚洲欧美电影在线观看| 亚洲欧美日韩精品在线| 国产主播精品在线| 欧美夫妇交换俱乐部在线观看| 欧美aⅴ一区二区三区视频| 99re66热这里只有精品4| 亚洲美女av在线播放| 国产精品美女久久久久久免费| 欧美在线视频免费播放| 久久久久久69| 一区二区三区www| 亚洲一区在线播放| 国户精品久久久久久久久久久不卡| 久久精品综合网| 欧美成人免费va影院高清| aa级大片欧美| 欧美一区二区三区视频在线| 亚洲第一福利在线观看| 99re在线精品| 国产午夜精品全部视频在线播放| 开元免费观看欧美电视剧网站| 麻豆av一区二区三区| 亚洲一区在线观看免费观看电影高清| 亚洲欧美三级在线| 亚洲精品日韩在线| 亚洲字幕一区二区| 亚洲激情国产精品| 亚洲一区激情| 亚洲精品国产拍免费91在线| 久久精品国产久精国产爱| 午夜亚洲福利| 久久9热精品视频| 亚洲人体影院| 亚洲视频免费在线| 亚洲国产高清高潮精品美女| 99国产精品久久久久久久久久| 国产精品腿扒开做爽爽爽挤奶网站| 麻豆精品视频在线观看视频| 欧美日韩国产综合视频在线观看中文| 久久国产婷婷国产香蕉| 欧美人成在线| 欧美jizzhd精品欧美巨大免费| 欧美日韩精品免费观看| 久久综合成人精品亚洲另类欧美| 欧美国产精品专区| 久久综合国产精品| 国产精品久久久久9999高清| 欧美黄色日本| 国产在线视频欧美一区二区三区| 亚洲精品永久免费精品| 在线精品亚洲| 久久国产精品久久w女人spa| 一区二区三区日韩| 欧美大片第1页| 久久久久五月天| 国产精品丝袜xxxxxxx| 亚洲欧洲精品一区二区三区不卡 | 毛片一区二区| 久久久久久日产精品| 欧美日韩视频专区在线播放 | 亚洲视频免费| 欧美韩日视频| 亚洲第一狼人社区| 精品二区视频| 久久九九国产精品怡红院| 新狼窝色av性久久久久久| 欧美日韩在线免费视频| 亚洲精品久久久久久一区二区 | 亚洲免费观看高清在线观看 | 亚洲激情在线观看| 久久综合九色九九| 麻豆久久婷婷| 亚洲国产另类精品专区| 美女网站在线免费欧美精品| 老司机成人网| 亚洲福利视频网| 欧美肥婆在线| 99视频精品全部免费在线| 麻豆av福利av久久av| 欧美激情网站在线观看| 亚洲人永久免费| 欧美日韩精品一区二区在线播放| 亚洲精品九九| 亚洲欧美美女| 国产日韩欧美制服另类| 欧美在线日韩| 亚洲国产精品一区| 亚洲午夜性刺激影院| 欧美天堂亚洲电影院在线观看| 在线中文字幕日韩| 欧美自拍偷拍午夜视频| 激情婷婷亚洲| 欧美日本精品一区二区三区| 一区二区三区日韩精品视频| 久久精品五月婷婷| 亚洲人体偷拍| 国产精品日韩欧美一区二区| 久久精品系列| 亚洲人成网站影音先锋播放| 亚洲欧美久久久| 国产专区综合网| 欧美激情1区2区3区| 亚洲一区尤物| 亚洲国产午夜| 久久久久**毛片大全| 亚洲乱码国产乱码精品精98午夜| 欧美日产国产成人免费图片| 香蕉亚洲视频| 亚洲精品女人| 亚洲男女自偷自拍图片另类| 国产又爽又黄的激情精品视频| 老鸭窝91久久精品色噜噜导演| 亚洲日韩欧美视频一区| 久久se精品一区精品二区| 亚洲黄色免费网站| 国产精品一区二区你懂得 | 欧美日韩高清不卡| 午夜一区二区三区不卡视频| 亚洲韩国青草视频| 久久激情视频久久| 99精品久久久| 亚洲国产99| 国产综合久久久久久| 欧美日韩免费在线| 欧美国产精品日韩| 免费观看日韩av| 久久精品夜色噜噜亚洲aⅴ| 国产精品99久久久久久久久久久久 |