1.如何创建一个DLL项目?
用vs2012创建一个新的Win32 应用控制台程序,名字取为math,要勾选dll选项。
如图:
然后新建mymath.h和mymath.cpp文件。
mymath.h如下:
#pragma once
#ifdef MATH_EXPORTS
#define MATH_API __declspec(dllexport)
#else
#define MATH_API __declspec(dllimport)
#endif
namespace shun
{
class MATH_API Cmath { //类
public:
int add(int a,int b);
};
extern "C" MATH_API float pi; //变量
extern "C" MATH_API int getMax(int &,int &); //函数
}
mymath.cpp如下:
#include "stdafx.h"
#include "mymath.h"
namespace shun
{
float pi=3.1415; //变量
int getMax(int& a, int& b) //函数
{
return a > b ? a : b;
}
int Cmath::add(int a,int b) //类方法
{
return a + b;
}
}
然后生成解决方案,编译成功后可以在debug文件夹下发现math.dll和math.lib文件。
至此,我们已经成功创建一个dll项目了。
2.如何隐式引用一个DLL项目?
隐式调用三要素,.h文件 ,.dll文件,.lib文件,缺一不可。
隐式调用的好处是可以像调用本地函数一样方便。
2.1如果项目和dll项目在同一个解决方案
为此我们新建一个win32控制台的空项目,取名useMath,然后引用dll步骤如下:
项目->属性->通用属性->框架和引用->添加新引用->勾选math项目->确定
项目->属性->配置属性->VC++目录->包含目录->添加mymath.h所在的目录
然后添加一个test.cpp文件,输入如下:
#include <iostream>
#include "mymath.h"
using namespace std;
int main(char argc, char**argv)
{
int a = 1, b = 2;
//类的使用
shun::Cmath cm;
cout<<cm.add(1,2)<<endl;
//变量
cout<<shun::pi<<endl;
//函数
cout<<shun::getMax(a,b);
getchar();
return 0;
}
运行一下我们发现调用dll项目了有木有。。
2.2如果项目和dll项目不在同一个解决方案呢?
为此,我们先打开一个新的vs2012,新建一个win32控制台的空项目,取名useMath,然后引用dll步骤如下:
项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件mymath.h所在的目录
项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件math.lib所在的目录
项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“math.lib”(若有多个 lib 则以空格隔开)
将dll项目下的debug文件中的math.dll复制到当前项目的debug文件夹中
新建然后添加一个test.cpp文件,输入如下:(和之前一样)
#include <iostream>
#include "mymath.h"
using namespace std;
int main(char argc, char**argv)
{
int a = 1, b = 2;
//类的使用
shun::Cmath cm;
cout<<cm.add(1,2)<<endl;
//变量
cout<<shun::pi<<endl;
//函数
cout<<shun::getMax(a,b);
getchar();
return 0;
}
3.如何显示调用dll项目?
显示调用只需要一个dll文件。显示调用好处是模块相对独立,更新非常方便。不好的地方是使用起来稍微复杂。
同之前一样,我们新建一个win32控制台项目,然后将math.dll放入debug文件夹中,
因为需要使用到windows api,所以要引入windows.h头文件。
添加test.cpp如下:
#include <windows.h>
#include <iostream>
using namespace std;
typedef int (*Func)(int &, int &);
int main(int argc, char *argv[])
{
int a = 5, b = 10;
HMODULE hDll = LoadLibrary("math.dll");
if (hDll != NULL)
{
Func getMax = (Func)GetProcAddress(hDll, "getMax"); //函数
if (getMax != NULL)
{
cout<<getMax(a, b)<<endl;
}
float* pPi = (float*)GetProcAddress(hDll,"pi"); //变量
if(pPi != NULL)
{
cout<<*pPi<<endl;
}
FreeLibrary(hDll);
}
getchar();
}
4.VS调试dll详细过程记录
前言:
在我们写的程序中有时候调用dll,并且需要跟踪dll中的函数,此时直接调试调用dll的工程是无法跳进dll的函数的,此时我们可以启动dll工程 来跟踪程序的走向。注意:要有dll的工程,也就是有其源代码,因为我们要在源代码里面打断点。具体步骤如下:
------------------------------------------------------------------------------------------------------------------------------------------
在这里有两个工程:一个是产生dll的工程:FastStrDLL ------------------用来调试的工程
一个是调用dll的工程:DllReuse -----------------提供调用dll的exe文件
------------------------------------------------------------------------------------------------------------------------------------------