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
30 00001700 PSEgetLibName
21 00001710 PSEgetLibType
42 00001720 PSEgetLibVersion
63 00001800 SPUabout
114 00001EE0 SPUclose
55 00001730 SPUconfigure
186 00002090 SPUgetOne
77 00001910 SPUinit
108 00001B90 SPUopen
239 00002270 SPUplayADPCMchannel
12A 00002250 SPUplaySample
17B 00002050 SPUputOne
19C 000020B0 SPUsetAddr
20D 000020E0 SPUsetPitch
21E 00002110 SPUsetVolumeL
22F 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的功能。
不知道还有没有什么遗漏啊,请大家指教了......
多提意见:)