DLL基本应用
编写DLL模块
调用DLL模块
编写DLL模块
DLL有三种类型:Non-MFC DLL、Regular DLL、Extension DLL。本文主要以Non-MFC DLL为主。
在VS2010中创建一个DLL工程,选择Win32控制台选项中的DLL选项。为了方便,我们选择非空项目,这样VS2010会为我们创建好基本框架,包含DLL模块的入口点DllMain函数。
一般Dll模块中,有三种类型可以导出:全局变量、函数、类。导出方法也有两种,一种是通过使用__declspec(dllexport),添加到需要导出的函数前,进行声明;另外一种就是通过模块定义文件(Module-Definition File即.DEF)来进行声明,这里我们只介绍第一种。
//MyDll.h
#pragma once
#ifdef _MYDLL_H_
#define MYDLLAPI __declspec(dllexport)
#else
#define MYDLLAPI __declspec(dllimport)
#endif
//导出类
class MYDLLAPI MyDll
{
public:
MyDll();
virtual ~MyDll();
virtual int func();
};
//如果想用显示的方法调用类对象,可以采用如下方式
extern "C" MYDLLAPI MyDll* CreateObject()
{
return new MyDll;
}
//导出函数
extern "C" MYDLLAPI void Dllfunc(int);
//全局变量
MYDLLAPI extern int Dlldata;
#undef _MYDLL_H_
//MyDll.cpp
#define _MYDLL_H_
#include "MyDll.h"
MyDll::MyDll()
{
}
MyDll::~MyDll()
{
}
int MyDll::func()
{
return 0;
}
void Dllfunc(int a)
{
Dlldata = a;
}
说明:
__declspec(dllexport)
表示导出,就是从DLL模块中导出到使用DLL的应用程序中去;
__declspec(dllimport)
表示导入,就是使用DLL的应用程序在调用DLL时,需要导入DLL模块中的内容。在DLL实现文件中采用#define _MYDLL_H_
方式区分导出和导入。extern “C”表示以C的方式编译函数,由于在C++中函数编译方式和C中不一致,为了调用正确,可以统一采用C的方式编译函数。
正确编译后,会产生两个文件:MyDll.lib和MyDll.dll。
调用DLL模块
应用程序调用DLL模块,有两种方式:隐式调用和显示调用。
- 隐式调用
需要DLL模块的三个文件:MyDll.h、 MyDll.lib、 MyDll.dll。建议MyDll.h和Mydll.lib这两个文件放到工程目录下,MyDll.dll放到执行程序目录下。
//Test.cpp
#include "MyDll.h"
#include <iostream>
using namespace std;
#pragma comment(lib, "MyDll.dll")
int Dlldata; //Dll 全局变量导出声明
int main()
{
//Dll导出类
MyDll mydll;
cout<<mydll.func()<<endl;
//Dll导出变量
Dlldata = 1;
cout<<Dlldata<<endl;
//Dll导出函数
Dllfunc(2);
cout<<Dlldata<<endl;
return 0;
}
- 显示调用
只需要DLL模块的一个文件:MyDll.dll。但是如果是显示调用一个类,还需要MyDll.h(包含MyDll类的定义)。MyDll.dll放到执行程序目录下。
//Test.cpp
#include "MyDll.h" //for MyDll调用
#include <iostream>
using namespace std;
//声明函数指针,对应Dll模块中的函数
typedef void (*DLLFUNC)(int);
typedef MyDll* (*CREATEOBJECT)();
int main()
{
//Dll导出类
CREATEOBJECT cobj;
cobj= (CREATEOBJECT)
HINSTANCE hinstance = LoadLibrary("MyDll.dll");
if (NULL == hinstance)
{
FreeLibrary(hinstance);
cerr<<"LoadLibrary fail";
return -1;
}
cobj = (CREATEOBJECT)GetProcAddress(hinstance, "CreateObject");
if(NULL == cobj)
{
FreeLibrary(hinstance);
cerr<<"Load Address fail";
return -1;
}
MyDll* pmydll = (*CREATEOBJECT)();
if (pmydll == NULL)
{
FreeLibrary(hinstance);
cerr<<"MyDll Class create fail";
return -1;
}
//Dll导出函数,与上面相同
//Dll导出变量
int dlldata;
dlldata = *(int *)GetProcAddress(hinstance, "Dlldata");
FreeLibrary(hinstance);
return 0;
}