delete this,dll導出類及如何寫plugins(PART III) [轉]

3.實現plugins。
有了前兩章的基礎,這個就比較好辦了。
先了解一點點基本概念:
Q:what is plugins
A:就是通過加載不同的dll實現不同的功能,或者附加的功能,典型的如模擬器的各種插件(顯示,input...)。
Q:why we use plugins
A:主要爲了使程序模塊化,並且容易擴充。升級組件時不需要重新發布整個產品。
Q:how to do it?
A:使用LoadLibrary來加載具有相同接口(一般是函數,不過我們這裏會使用C++類實現)的不同dll,實現/(擴充)功能。
例子:
D:/ePsxe/plugins>dumpbin spuseal.dll /exports
Microsoft (R) COFF Binary File Dumper Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file spuseal.dll
File Type: DLL
 Section contains the following exports for spuSeal.dll
      0 characteristics
  36A22A22 time date stamp Sun Jan 17 10:21:22 1999
    0.00 version
      2 ordinal base
     22 number of functions
     22 number of names
  ordinal hint RVA    name
      3  0 00001700 PSEgetLibName
      2  1 00001710 PSEgetLibType
      4  2 00001720 PSEgetLibVersion
      6  3 00001800 SPUabout
     11  4 00001EE0 SPUclose
      5  5 00001730 SPUconfigure
     18  6 00002090 SPUgetOne
      7  7 00001910 SPUinit
     10  8 00001B90 SPUopen
     23  9 00002270 SPUplayADPCMchannel
     12  A 00002250 SPUplaySample
     17  B 00002050 SPUputOne
     19  C 000020B0 SPUsetAddr
     20  D 000020E0 SPUsetPitch
     21  E 00002110 SPUsetVolumeL
     22  F 00002150 SPUsetVolumeR
      8  10 00001B80 SPUshutdown
     13  11 00002190 SPUstartChannels1
     14  12 000021C0 SPUstartChannels2
     15  13 000021F0 SPUstopChannels1
     16  14 00002220 SPUstopChannels2
      9  15 00001880 SPUtest
 Summary
    1000 .rsrc
    96000 UPX0
    5000 UPX1
D:/ePsxe/plugins>

這個是epsxe的一個sound插件的輸出表。可以看到epsxe就是通過這些函數與dll通信的。
進入正題:
從一個dll裏面輸出這麼多函數實在是一個很煩的事情,而且一個個的去GetProcAddr也很麻煩,
能不能用簡單一些的方法呢?
當然是可以的了,使用我們前面介紹的dll輸出類技術2就可以了。
還是看代碼,我們做一個input的plugins類。
;//input.h
class input{
virtual int  Addref()=0;
virtual int  Release()=0;
virtual DWORD  QueryClsID()=0;//identify this is a input plugins;
virtual DWORD  IsSupport(DWORD flags)=0;
virtual bool  GetXY(int&x,int&y)=0;
virtual DWORD  GetButtonStat()=0;
virtual bool AddEffect(DWORD id,DWORD level)=0;
virtual bool QueryInterface(DWORD clsid,LPVOID* ppVoid);//留待擴充。越來越像COM了。
virtual bool DoConfig();
protected:
input();
virtual ~input();
};
--------------------------------------------------------
;//mouseinput.h
class MouseInput
 :public input
{
protected:
friend input* CreateInput(LPVOID pVoid);
;//...............
};
--------------------------------------------------------
;//mouseinput.cpp
input* CreateInput(LPVOID pVoid){return new mouseinput;};
 
--------------------------------------------------------
;//keyinput.h
class KeyInput
 :public input
{
protected:
friend input* CreateInput(LPVOID pVoid);
;//...............
};
--------------------------------------------------------
;//keyinput.cpp
input* CreateInput(LPVOID pVoid){return new keyinput;};
 
編譯後就得到了mouseinput.dll和keyinput.dll
他們分別輸出mouseinput類和keyinput類,而外部程序是通過input的接口來調用他們,從而實現了plugins的功能。
 
 
不知道還有沒有什麼遺漏啊,請大家指教了......
 
多提意見:)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章