后面项目可能要封装一些API到DLL中,供应用层使用,所以今天研究了下DLL:
第一步,建立DLL项目:
为了建立项目,请选择Win32 控制台项目(Win32 Console Application),并且在设应用程序设置标签(the advanced tab)上,选择DLL和空项目选项。
第二步,DLL头文件
首先写你的头文件(header file);称为DLLTutorial.h。这个文件与其它头文件一样,其中只是一些函数的原型。
#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#define DLL_EXPORT
#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Print( void );
}
#endif
说明:
__declspec(dllexport):
将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。
通常它和extern "C" 合用,extern "C"告诉编译器该部分可以在C/C++中使用,形式如下:
extern "C"
{
__declspec(dllexport) RETURN_TYPE FUNCTION()
}
#include "stdafx.h"
#include <iostream>
#include "DLLTutorial.h"
extern "C"
{
DECLDIR int Add( int a, int b )
{
return( a + b );
}
DECLDIR void Print( void )
{
std::cout << "DLL Called!" << std::endl;
}
}
第四步,测试使用DLL
方法一,显示调用:
#include <iostream>
#include <windows.h>
typedef int (*AddFunc)(int,int);
typedef void (*PrintFunc)();
int main()
{
AddFunc _AddFunc;
PrintFunc _PrintFunc;
//HINSTANCE hInstLibrary = ::LoadLibrary(L"DLLTutorial.dll");
HINSTANCE hInstLibrary =LoadLibraryEx(L"D:\\WorkSpace\\DLLTutorial\\Debug\\DLLTutorial.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
DWORD dwErr = ::GetLastError();
if (hInstLibrary == NULL)
{
FreeLibrary(hInstLibrary);
return 0;
}
_AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
_PrintFunc = (PrintFunc)GetProcAddress(hInstLibrary, "Print");
if ((_AddFunc == NULL) || (_PrintFunc == NULL))
{
FreeLibrary(hInstLibrary);
}
std::cout << _AddFunc(45, 54) << std::endl;
_PrintFunc();
system("pause");
FreeLibrary(hInstLibrary);
return 1;
}
注意:
这里显示调用的时候,LoadLibrary或者LoadLibraryEx调用的时候,我将dll路径强转成LPCWSTR,一直加载不了dll,报错错误码是126,后来改成L就能加载成功了。比较郁闷。
后来查了资料,原来是unicode的原因:http://blog.csdn.net/longlong530/article/details/9137197
方法二,隐式调用:
1.准备DLLTutorial.h,DLLTutorial.lib,DLLTutorial.dll
2.链接到DLLTutorial.lib文件(项目属性设置 或者#pragma comment(lib, "DLLTutorial.lib"))
3.引用DLLTutorial.h头文件
#include <iostream>
#include <DLLTutorial.h>
int main()
{
Print();
std::cout << Add(32, 58) << "/n"; return 0;
}
注意:
1.一个HINSTANCE是一个Windows数据类型:是一个实例的句柄;在此情况下,这个实例将是这个DLL。你可以通过使用函数LoadLibrary()获得DLL的实例。
2.获得了指向DLL的句柄后,使用函数GetProcAddress(),它将DLL的句柄(你可以使用HINSTANCE)和函数的名称作为参数。你可以让函数指针获得由GetProcAddress()返回的值,同时你必需将GetProcAddress()转换为那个函数定义的函数指针。
3.你不能使用DLL函数的实际名称;你必需使用函数指针来调用它们。
代码已经上传,比较简单,仅供参考: