其 实VS下面开发C++的DLL还是很方便的,而且Release的时候也很方便,只要把模块的只能划分清楚,封装好不同的DLL工程,在一个主工程里面引 用这些不同的DLL工程还是很不错的,这样发布的时候有一个主工程的EXE 和不同的DLL就可以了,不论是调试还是Release都比较简单,下面就简单说说开发的过程。
方案一:
在VS2005下创建项目后,选择WIN32控制台应用程序,到了应用程序设置时选择DLL应用程序类型,附加选项选择空项目。创建好以后添加Dll1.cpp文件。
以下是Dll1.cpp文件:
- #define DLL1_API _declspec(dllexport)
-
- #include <iostream>
-
- using namespace std;
- DLL1_API int add(int a,int b)
- {
- return a+b;
- }
- DLL1_API int subtract(int a,int b)
- {
- return a-b;
- }
#define DLL1_API _declspec(dllexport) //定义DLL1_API 为_declspec(dllexport) ,并且解决在不同语言调用下的名字匹配问题 #include <iostream> //#include "Dll1.h" using namespace std; DLL1_API int add(int a,int b) //实现两个整数相加 { return a+b; } DLL1_API int subtract(int a,int b) //实现两个整数相减 { return a-b; }
编译以后在Debug文件下生成一个Dll1.dll的动态链接库文件。在DOS下打开此文件目录,并把你安装VS2005的目录下 (D:\Microsoft Visual Studio 8\VC\bin--我的VS2005安装在D盘)找到vcvars32.bat此文件,把它托放在你的DOS对话框里面,单击回车后运行 dumpbin -exports Dll1.dll就可以查到你生成的DLL里面所包含的所实现的两个函数的具体信息:
- ordinal hint RVA name
- 1 0 00011087 ?add@@YAHHH@Z = @ILT+130(?add@@YAHHH@Z)
- 2 1 00011073 ?subtract@@YAHHH@Z = @ILT+110(?subtract@@YAHHH@Z)
ordinal hint RVA name 1 0 00011087 ?add@@YAHHH@Z = @ILT+130(?add@@YAHHH@Z) 2 1 00011073 ?subtract@@YAHHH@Z = @ILT+110(?subtract@@YAHHH@Z)
第一个参数在后面的调用有一个应用方法,最后的name就是实现函数的名字。
现在再打开你的Debug文件你会发现里面多出来一个Dll1.lib文件,dumpbin -exports Dll1.dll也就实现的了函数的导出。
下面来介绍一下用.dll和 .lib文件实现调用动态链接库。
在VS2005下正常创建一个WIN32控制台应用程序后,编写CPP文件。并把刚才生成的Dll1.dll和Dll1.lib文件拷到此工程目录下。并打开工程->属性->编译链接器->输入->附加信赖项,在里编写Dll1.lib。
- #include <iostream>
- using namespace std;
- extern int add(int a,int b);
- extern int subtract(int a,int b);
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- int a,b;
- while(cin>>a>>b)
- {
- cout<<"Add is = "<<add(a,b)<<endl;
- cout<<"Subtract is = "<<subtract(a,b)<<endl;
- }
- return 0;
- }
#include <iostream> using namespace std; extern int add(int a,int b); //相当于在外部已编写此函数,在此声明 extern int subtract(int a,int b); // _declspec(dllimport) int add(int a,int b); //这个也可以,效率更高--告诉编译器是从DLL里面调用 // _declspec(dllimport) int subtract(int a,int b); int _tmain(int argc, _TCHAR* argv[]) { int a,b; while(cin>>a>>b) { cout<<"Add is = "<<add(a,b)<<endl; //直接调用DLL里面的函数 cout<<"Subtract is = "<<subtract(a,b)<<endl; } return 0; }
方案二:
重新创建一个DLL的应用程序,并选择空项目。添加DLL1.cpp文件,如下:
- #define DLL1_API /*extern "C"* / _declspec(dllexport) //加上extern "C"-(C大写)可以让C++编写的DLL在其他语言中也可以调用,DOS下执 行dumpbin -exports Dll1.dll时可以看到函数名的变化。但是使用extern "C"的缺陷是不能导出C++的类成员函数,只能 导出全局函数。使名字不发生改变
- #include "Dll1.h"
- Int add(int a,int b)
- {
- return a+b;
- }
- int subtract(int a,int b)
- {
- return a-b;
- }
#define DLL1_API /*extern "C"*/ _declspec(dllexport) //加上extern "C"-(C大写)可以让C++编写的DLL在其他语言中也可以调用,DOS下执行dumpbin -exports Dll1.dll时可以看到函数名的变化。但是使用extern "C"的缺陷是不能导出C++的类成员函数,只能导出全局函数。使名字不发生改变 #include "Dll1.h" Int add(int a,int b) { return a+b; } int subtract(int a,int b) { return a-b; }
添加Dll1.h文件:
- #ifdef DLL1_API
- #else
- #define DLL1_API /*extern "C"*/ _declspec(dllimport) //同.cpp文件中同步
- #endif
- DLL1_API int add(int a,int b);
- DLL1_API int subtract(int a,int b);
#ifdef DLL1_API #else #define DLL1_API /*extern "C"*/ _declspec(dllimport) //同.cpp文件中同步 #endif DLL1_API int add(int a,int b); //表明函数是从DLL导入,给客户端使用 DLL1_API int subtract(int a,int b);
编译此工程,再创建一个WIN32控制台应用程序,在工程属性里面的附加信赖项加入Dll1.lib,并在工程目录下重新拷贝Dll1.dll和Dll1.lib。代码如下:
- #include <iostream>
- using namespace std;
- #include "..\..\Dll1\Dll1\Dll1.h" //添加上面工程的.h文件所以路径
-
-
-
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- int a,b;
- while(cin>>a>>b)
- {
- cout<<"Add is = "<<add(a,b)<<endl;
- cout<<"Subtract is = "<<subtract(a,b)<<endl;
- }
- return 0;
- }
#include <iostream> using namespace std; #include "..\..\Dll1\Dll1\Dll1.h" //添加上面工程的.h文件所以路径 //extern int add(int a,int b); //相当于在外部已编写此函数,在此声明 --可以省略 //extern int subtract(int a,int b); // _declspec(dllimport) int add(int a,int b); //这个也可以,效率更高--告诉编译器是从DLL里面调用--可以省略 // _declspec(dllimport) int subtract(int a,int b); int _tmain(int argc, _TCHAR* argv[]) { int a,b; while(cin>>a>>b) { cout<<"Add is = "<<add(a,b)<<endl; //直接调用DLL里面的函数 cout<<"Subtract is = "<<subtract(a,b)<<endl; } return 0; }
如果需要导出一个类,头文件为:
- #pragma once
-
- #ifdef DLL_API
- #else
- #define DLL_API __declspec(dllimport)
- #endif
-
- class DLL_API Test
- {
- public:
- Test(void);
- public:
- ~Test(void);
-
- void show();
- };