VC2008如何生成及使用DLL(完整版)
2013-12-10 15:49
357 查看
生成、使用DLL看起来简单,但做起来才发现还是有一些地方需要注意的。
1. 打开VS2008,新建一个VC工程,选择Win32类型,Win32项目:
![](http://p.blog.csdn.net/images/p_blog_csdn_net/codehat/EntryImages/20090812/1.JPG)
2. 应用程序类型选择DLL,附加选项选择到处符号,公共头文件不要选择,然后点完成即可。
![](http://dl.iteye.com/upload/attachment/524136/9e0ea224-ee70-30e1-9f31-c7e8c549c257.jpg)
3. 工程生成后需要修改属性,在配置属性的常规选项中将MFC的使用修改为“静态库中使用MFC”。
注意,这一步是必须的,否则写出来的DLL将需要在有VC2008的环境上才能运行。
![](http://dl.iteye.com/upload/attachment/524140/fa1160b7-bc12-3d38-afa1-59eebe30fc2b.jpg)
4. 关注自动生成的文件MyDllTest.cpp,其中有几个实例,可以将他们删除,也可以不管他们。
5. 添加自己的接口,如:GetMyDllVersion
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 得到当前DLL的版本号
MYDLLTEST_API UINT32 GetMyDllVerion( VOID )
{
return 1234;
}
6. 在头文件MyDllTest.h中添加声明
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
MYDLLTEST_API UINT32 GetMyDllVerion( VOID );
7. 添加导出符号定义文件,理论上是可以不要导出定义的,但是那样的结果就是生成的DLL中的符号名字不明确,只有定义了导出符号,才可以使得DLL中的借口函数名称得以确定。(关于def与dll 请参阅msdn )
![](http://dl.iteye.com/upload/attachment/524245/3bd020fa-df96-3121-a673-2cd6c6e435da.jpg)
文件内容:
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
LIBRARY "MyDllTest"
EXPORTS
GetMyDllVerion
8. 在项目属性中设置模块定义文件为刚才建立的symexport.def文件:
![](http://p.blog.csdn.net/images/p_blog_csdn_net/codehat/EntryImages/20090812/2.JPG)
9. 生成,可以得到一个MyDllTest.dll,使用Depends工具(VC6.0自带)可以查看这个DLL中包含了多少接口以及接口名:
![](http://p.blog.csdn.net/images/p_blog_csdn_net/codehat/EntryImages/20090812/3.JPG)
会发现除了我们定义的借口GetMyDllVersion外还有几个??开头的接口,他们就是那些没有在模块定义文件中定义的借口自动生成的。
10. 除了DLL外我们还会发现生成了MyDllTest.lib文件,这个lib文件可以在其他的程序使用这个DLL的时候将其连接进去,同时只要包含MyDllTest.h即可调用这个DLL中的借口了。
如何引入dll
方法一.装载期间动态加载。(需要lib和dll)
1。新建Win32应用程序空项目。
2。把生成的dll、lib这2个文件复制到新建的目录下。
3。添加导入库:工具--项目和解决方案(vs里是options)--VC++目录,选择右侧“显示以下内容的目录”下的“库文件”,把lib所在目录添加。
![](http://dl.iteye.com/upload/attachment/524305/4f1330ec-3bc2-3a82-9b9c-4bc668c276dd.jpg)
4。头文件:MyDllTest.h(与编写DLL中一样)
5。源文件:main.c
可注释#pragma comment(lib," MyDllTest.lib")这条,但必须设置链接库,方法:
右击项目--属性--配置属性--链接器--输入--附加依赖项: MyDllTest.lib
#include " MyDllTest.h"
#include " windows.h"
#pragma comment(lib," MyDllTest.lib")
int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
GetMyDllVersion();
return 0;
}
方法二:运行期间动态加载。(只需Dll文件即可)
需要使用 Windows API 函数: LoadLibrary 、 GetProcAddress 以及 FreeLibrary
#include <iostream>
#include <windows.h>
using namespace std;
//定义FunctionFunc为指向一个返回值为int型 无参数的函数的指针
typedef int (*FunctionFunc)();
int main()
{
FunctionFunc _FunctionFunc;
//加载目标Dll
HMODULE hModule = ::LoadLibrary (TEXT("D:\MyDllTest.dll"));
if (hModule==NULL)//如果Dll加载失败,释放它占用的资源
{
::FreeLibrary(hModule);
}
//取得目标Dll中导出函数的地址(提醒:函数名就是函数的入口地址)
_FunctionFunc=(FunctionFunc)::GetProcAddress (hModule,"GetMyDllVersion");
if (_FunctionFunc==NULL)
{
::FreeLibrary (hModule);
}
int a =_FunctionFunc();
cout<< a<<endl;
::FreeLibrary(hModule);
cin.get();
return 1;
}
有时候我们拿到的是别人的DLL和头文件,但是却没有LIB文件,这时就要使用另外的方法调用DLL中的接口了,例如MD5接口的使用:
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 按照MSDN中的说明定义函数原型如下
typedef struct
{
ULONG i[2];
ULONG buf[4];
unsigned char in[64];
unsigned char digest[16];
} MD5_CTX;
typedef void (CALLBACK* MD5Init_Tpye)(MD5_CTX* context);
typedef void (CALLBACK* MD5Update_Tpye)(MD5_CTX* context,
unsigned char * input,
unsigned int inlen);
typedef void (CALLBACK* MD5Final_Tpye)(MD5_CTX* context);
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 使用MD5接口
HINSTANCE hDLL;
// MD5接口是在Cryptdll.dll中的
hDLL = LoadLibrary(TEXT("Cryptdll.dll" ));
MD5Init_Tpye MD5Init;
MD5Update_Tpye MD5Update;
MD5Final_Tpye MD5Final;
// 得到接口指针
MD5Init = (MD5Init_Tpye)GetProcAddress(hDLL, "MD5Init" );
MD5Update = (MD5Update_Tpye)GetProcAddress(hDLL, "MD5Update" );
MD5Final = (MD5Final_Tpye)GetProcAddress(hDLL, "MD5Final" );
if (!MD5Init || !MD5Update || !MD5Final)
{
// 取得接口指针失败
FreeLibrary(hDLL);
return ;
}
MD5_CTX md5_context;
MD5Init(&md5_context);
MD5Update(&md5_context, src, length);
MD5Final(&md5_context);
// 不要忘记释放导入的DLL
FreeLibrary(hDLL);
这就是目前我知道的两种使用DLL的方法了,至于还有没有其他的方法,暂时没有这方面的需求,也就不去花脑力想了。。。
1. 打开VS2008,新建一个VC工程,选择Win32类型,Win32项目:
2. 应用程序类型选择DLL,附加选项选择到处符号,公共头文件不要选择,然后点完成即可。
![](http://dl.iteye.com/upload/attachment/524136/9e0ea224-ee70-30e1-9f31-c7e8c549c257.jpg)
3. 工程生成后需要修改属性,在配置属性的常规选项中将MFC的使用修改为“静态库中使用MFC”。
注意,这一步是必须的,否则写出来的DLL将需要在有VC2008的环境上才能运行。
![](http://dl.iteye.com/upload/attachment/524140/fa1160b7-bc12-3d38-afa1-59eebe30fc2b.jpg)
4. 关注自动生成的文件MyDllTest.cpp,其中有几个实例,可以将他们删除,也可以不管他们。
5. 添加自己的接口,如:GetMyDllVersion
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 得到当前DLL的版本号
MYDLLTEST_API UINT32 GetMyDllVerion( VOID )
{
return 1234;
}
6. 在头文件MyDllTest.h中添加声明
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
MYDLLTEST_API UINT32 GetMyDllVerion( VOID );
7. 添加导出符号定义文件,理论上是可以不要导出定义的,但是那样的结果就是生成的DLL中的符号名字不明确,只有定义了导出符号,才可以使得DLL中的借口函数名称得以确定。(关于def与dll 请参阅msdn )
![](http://dl.iteye.com/upload/attachment/524245/3bd020fa-df96-3121-a673-2cd6c6e435da.jpg)
文件内容:
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
LIBRARY "MyDllTest"
EXPORTS
GetMyDllVerion
8. 在项目属性中设置模块定义文件为刚才建立的symexport.def文件:
9. 生成,可以得到一个MyDllTest.dll,使用Depends工具(VC6.0自带)可以查看这个DLL中包含了多少接口以及接口名:
会发现除了我们定义的借口GetMyDllVersion外还有几个??开头的接口,他们就是那些没有在模块定义文件中定义的借口自动生成的。
10. 除了DLL外我们还会发现生成了MyDllTest.lib文件,这个lib文件可以在其他的程序使用这个DLL的时候将其连接进去,同时只要包含MyDllTest.h即可调用这个DLL中的借口了。
如何引入dll
方法一.装载期间动态加载。(需要lib和dll)
1。新建Win32应用程序空项目。
2。把生成的dll、lib这2个文件复制到新建的目录下。
3。添加导入库:工具--项目和解决方案(vs里是options)--VC++目录,选择右侧“显示以下内容的目录”下的“库文件”,把lib所在目录添加。
![](http://dl.iteye.com/upload/attachment/524305/4f1330ec-3bc2-3a82-9b9c-4bc668c276dd.jpg)
4。头文件:MyDllTest.h(与编写DLL中一样)
5。源文件:main.c
可注释#pragma comment(lib," MyDllTest.lib")这条,但必须设置链接库,方法:
右击项目--属性--配置属性--链接器--输入--附加依赖项: MyDllTest.lib
#include " MyDllTest.h"
#include " windows.h"
#pragma comment(lib," MyDllTest.lib")
int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
GetMyDllVersion();
return 0;
}
方法二:运行期间动态加载。(只需Dll文件即可)
需要使用 Windows API 函数: LoadLibrary 、 GetProcAddress 以及 FreeLibrary
#include <iostream>
#include <windows.h>
using namespace std;
//定义FunctionFunc为指向一个返回值为int型 无参数的函数的指针
typedef int (*FunctionFunc)();
int main()
{
FunctionFunc _FunctionFunc;
//加载目标Dll
HMODULE hModule = ::LoadLibrary (TEXT("D:\MyDllTest.dll"));
if (hModule==NULL)//如果Dll加载失败,释放它占用的资源
{
::FreeLibrary(hModule);
}
//取得目标Dll中导出函数的地址(提醒:函数名就是函数的入口地址)
_FunctionFunc=(FunctionFunc)::GetProcAddress (hModule,"GetMyDllVersion");
if (_FunctionFunc==NULL)
{
::FreeLibrary (hModule);
}
int a =_FunctionFunc();
cout<< a<<endl;
::FreeLibrary(hModule);
cin.get();
return 1;
}
有时候我们拿到的是别人的DLL和头文件,但是却没有LIB文件,这时就要使用另外的方法调用DLL中的接口了,例如MD5接口的使用:
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 按照MSDN中的说明定义函数原型如下
typedef struct
{
ULONG i[2];
ULONG buf[4];
unsigned char in[64];
unsigned char digest[16];
} MD5_CTX;
typedef void (CALLBACK* MD5Init_Tpye)(MD5_CTX* context);
typedef void (CALLBACK* MD5Update_Tpye)(MD5_CTX* context,
unsigned char * input,
unsigned int inlen);
typedef void (CALLBACK* MD5Final_Tpye)(MD5_CTX* context);
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
// 使用MD5接口
HINSTANCE hDLL;
// MD5接口是在Cryptdll.dll中的
hDLL = LoadLibrary(TEXT("Cryptdll.dll" ));
MD5Init_Tpye MD5Init;
MD5Update_Tpye MD5Update;
MD5Final_Tpye MD5Final;
// 得到接口指针
MD5Init = (MD5Init_Tpye)GetProcAddress(hDLL, "MD5Init" );
MD5Update = (MD5Update_Tpye)GetProcAddress(hDLL, "MD5Update" );
MD5Final = (MD5Final_Tpye)GetProcAddress(hDLL, "MD5Final" );
if (!MD5Init || !MD5Update || !MD5Final)
{
// 取得接口指针失败
FreeLibrary(hDLL);
return ;
}
MD5_CTX md5_context;
MD5Init(&md5_context);
MD5Update(&md5_context, src, length);
MD5Final(&md5_context);
// 不要忘记释放导入的DLL
FreeLibrary(hDLL);
这就是目前我知道的两种使用DLL的方法了,至于还有没有其他的方法,暂时没有这方面的需求,也就不去花脑力想了。。。
相关文章推荐
- VC2008如何生成及使用DLL(完整版)
- VC2008如何生成及使用DLL(完整版)
- VC2008如何生成及使用DLL(完整版)
- VC2008如何生成及使用DLL(完整版)
- VC2008如何生成及使用DLL
- VC2008如何生成及使用DLL(完整版)
- C#中如何创建、生成以及使用DLL
- C/C++ 关于生成静态库(lib)/动态库(dll)文件如何使用(基于windows基础篇)
- 如何生成和使用DLL ——DLL入门浅析
- 如何从DLL中生成LIB文件
- php如何使用 phpqrcode 生成二维码
- 添加一个文件夹及一些文件如何使用git生成patch git补丁 新文件 图片资源文件
- 如何正确创建DLL和使用DLL
- 如何使用Maven的archetype快速生成一个新项目
- Android Studio 使用教程(二十一)之Android Studio如何快速生成get和set
- 如何使用vue-cli生成项目
- [Android Studio / NDK] 如何使用javah生成.h文件
- 如何使用silverlight加载动态库(dll)并发布到IIS7
- Solr4.0 如何配置使用UUID自动生成id值
- Android生成工具包时如何使用图片资源