实例分别使用了上述两种不同的引出方式,请留意。
2.DLL的调用
加载DLL时,Windows寻找相应DLL的次序如下:
?.当前工作盘。
?Windows目录;GetWindowsDirectory( )函数可提供该目录的路径名。
?Windows系统目录,即System子目录;调用GetSystemDiretory( )函数可获得这个目录的路径名。
?DOS的PATH命令中罗列的所有目录。
?网络中映象的目录列表中的全部目录。
DLL模块中输出函数的调用方法:
不论使用何种语言对编译好的DLL进行调用时,基本上都有两种调用方式,即静态调用方式和动态调用方式。静态调用方式由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。动态调用方式是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。具体来说,可用如下的方法调用:
?.在应用程序模块定义文件中,用IMPORTS语句列出所要调用DLL的函数名。如:
IMPORTS MEMORYDLL.MemoryRead
MEMORYDLL.MemoryWrite
?让应用程序运行时与DLL模块动态链接
先用LoadLibrary加载DLL,再用GetProcAddress函数检取其输出函数的地址,获得其指针来调用。如:
HANDLE hLibrary; FARPROC lpFunc; int PortValue; M hLibrary=LoadLibrary("PORTDLL.DLL"); //加载DLL if(hLibrary>31) //加载成功 { lpFunc=GetProcAddress(hLibrary,"PortIn"); //检取PortIn函数地址 if(lpFunc!=(FARPROC)NULL) //检取成功则调用 PortValue=(*lpFunc)(port); //读port端口的值 FreeLibrary(hLibrary); //释放占用的内存 } M
三、DLL应用实例源程序
1.直接内存访问的DLL源代码
//.DEF文件 LIBRARY MEMORYDLL DESCRIPTION ''DLL FOR MEMORY_READ_WRITE '' EXETYPE WINDOWS CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE SINGLE HEAPSIZE 1024 //DLL无自己的堆栈,故没有STACKSIZE语句 EXPORTS WEP @1 residentname ReadMemory @2 WriteMemory @3 //.CPP文件 #include <windows.h> int FAR PASCAL LibMain(HINSTANCE hInstance,WORD wDataSeg,WORD wHeapSize,LPSTR lpszCmdLine) { if(wHeapSize!=0) UnlockData(0); return 1; } int FAR PASCAL MemoryRead(unsigned int DosSeg,unsigned int DosOffset) { WORD wDataSelector,wSelector; char far *pData; char value; wDataSelector=HIWORD((DWORD)(WORD FAR *)&wDataSelector); wSelector=AllocSelector(wDataSelector); //分配选择器 SetSelectorLimit(wSelector,0x2000); //置存取界限 SetSelectorBase(wSelector,(((DWORD)DosSeg)<<4)+(DWORD)DosOffset); //置基地址 pData=(char far *)((DWORD)wSelector<<16); value=*pData; FreeSelector(wSelector); //释放选择器 return (value); } void FAR PASCAL MemoryWrite(unsigned int DosSeg,unsigned int DosOffset,char Data) { WORD wDataSelector,wSelector; char far *pData; wDataSelector=HIWORD((DWORD)(WORD FAR *)&wDataSelector); wSelector=AllocSelector(wDataSelector); SetSelectorLimit(wSelector,0x2000); SetSelectorBase(wSelector,(((DWORD)DosSeg)<<4)+(DWORD)DosOffset); pData=(char far *)((DWORD)wSelector<<16); *pData=Data; FreeSelector(wSelector); } int FAR PASCAL WEP(int nParam) { return 1; }
2.端口读写I/O的DLL源代码
//.DEF文件 LIBRARY PORTDLL DESCRIPTION ''DLL FOR PORT_IN_OUT '' EXETYPE WINDOWS CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD MOVEABLE SINGLE HEAPSIZE 1024 //.CP
|