DLL模块例1:使用.def模块导出函数,规范修饰名称,显示连接调用dll中函数
以下内容,我看了多篇文章,整合在一起,写的一个例子,关于dll工程的创建,请参考博客里另一篇文章:http://www.cnblogs.com/pingge/articles/3153571.html
有什么不对的欢迎指正!!!
1.头文件
1 //testdll.h 9 #ifndef _TESTDLL_H_ 10 #define _TESTDLL_H_ 11 12 namespace MathFuncs 13 { 14 // This class is exported from the testdll.dll 15 // Returns a + b 16 extern double _stdcall Add(double a, double b); 17 18 // Returns a - b 19 extern double _stdcall Subtract(double a, double b); 20 21 // Returns a * b 22 extern double _stdcall Multiply(double a, double b); 23 24 // Returns a / b 25 // Throws const std::invalid_argument& if b is 0 26 extern double _stdcall Divide(double a, double b); 27 } 28 29 #endif
以上是dll工程的头文件,使用命名空间,声明extern外部变量,_stdcall是WIN32API的一种函数调用约定,表示函数参数从右到左压入堆栈
1 // testdll.cpp : 定义 DLL 应用程序的导出函数。 2 3 #include "stdafx.h" 4 #include "testdll.h" 5 #include <stdexcept> 6 using namespace std; 7 8 namespace MathFuncs 9 { 10 double _stdcall Add(double a, double b) 11 { 12 return a + b; 13 } 14 15 double _stdcall Subtract(double a, double b) 16 { 17 return a - b; 18 } 19 20 double _stdcall Multiply(double a, double b) 21 { 22 return a * b; 23 } 24 25 double _stdcall Divide(double a, double b) 26 { 27 if (b == 0) 28 { 29 throw invalid_argument("b cannot be zero!"); 30 } 31 return a / b; 32 } 33 }
以上定义的dll工程的导出函数
1 LIBRARY testdll 2 EXPORTS 3 Add @ 1 4 Subtract @ 2 5 Multiply @ 3 6 Divide @ 4
在源文件目录里面添加.def文件,
第一行说明DEF文件对应的dll
EXPORTS后列出要导出函数的名称
可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);
可以用dumpbin.exe或者depends.exe来查看dll中函数的接口参数——序号,函数名等
1 //demo.cpp 2 #include <windows.h> 3 #include <iostream> 4 using namespace std; 5 6 int main() 7 { 8 double a = 7.4; 9 int b = 99; 10 //如果使用.def导出dll函数一定要加_stdcall 11 typedef double (_stdcall *pAdd) (double a,double b); 12 typedef double (_stdcall *pSubtract) (double a,double b); 13 HMODULE hDLL = LoadLibrary("testdll.dll"); //加载DLL文件 14 if(hDLL != NULL) 15 { 16 //得到dll中的第一个函数 17 pAdd fp1 = pAdd(GetProcAddress(hDLL,MAKEINTRESOURCE(1))); 18 19 if(fp1 != NULL) 20 { 21 cout << "a + b = " << 22 fp1(a, b) << endl; 23 } 24 else 25 { 26 cout << "Cannot Find Function " << "add" << endl; 27 } 28 29 //得到dll中的第二个函数 30 pSubtract fp2 = pSubtract(GetProcAddress(hDLL,"Subtract")); 31 if(fp2 != NULL) 32 { 33 cout << "a - b = " << 34 fp2(a, b) << endl; 35 } 36 else 37 { 38 cout << "Cannot Find Function " << "Subtract" << endl; 39 } 40 FreeLibrary(hDLL); 41 } 42 else 43 { 44 cout << "Cannot Find " << "testdll" << endl; 45 } 46 return 0; 47 }
以上为一个调用dll的demo,使用显示调用,需要用到WIN32 API函数,GetProcAddress(hDLL,MAKEINTRESOURCE(1));第一个这个函数的第二个参数的获得通过dll导出函数的序号获得,GetProcAddress(hDLL,"Subtract");第二个这个函数的第二个参数的获得通过导出函数的名字来获得,
导出函数,一定要采用.def模块 或者 extern "C"修饰符来做,传统方法做出来的导出函数的名字会被编译器修改优化,导致很麻烦的名字,例如"?Subtract@MyMathFuncs@MathFuncs@@SANNN@Z"
表达上的不足请见谅。。相关资料请参考MSDN还有“侯凯”的博客。。
——现在的努力是为了小时候吹过的牛B!!