在实际的工作中,我们经常会遇到这样问题:代码太多,各种调用之间转的人晕头转向。代码给合作机构,又怕核心代码泄密。
这时候我们想到的是用一种办法把我们的代码封起来,只给调用方式。但是对于初学者经常会被各种DLL,lib搞得晕头转向。下面是我自己整理的一些封库方式,如有错误,欢迎留言!!!
在这里关键,win32项目,选择DLL。这里在源文件有三个文件,前两个我们不用关心,后面一个是我们写DLL里面函数的文件。
#include "stdafx.h"
#include
//关键是这里,这里要用__declspec(dllexport) 想明白具体原因可以去百度。 后面接上你的函数定义。
__declspec(dllexport) void output();
void output()
{
using namespace std;
cout << "今天是2018年,10月,8号!!!" << endl;
}
之后就是编译,然后我们会在相应的目录Debug下找到DLL,LIB文件。
在这个插一个话题:
就是怎么看看我我们生成的dll文件。进入命令行模式,找到我们VS所在目录,VC/BIN下会有一个vcvars32.bat文件,直接运行它。然后在这个命令行下,我们可以进入对应上步生成的debug目录下。运行dumpbin -exports test.dll
但是这里会有一个问题,我们生成的DLL文件回是这个样子:
这里就是我们函数名称被C++编译一种特殊格式了,具体是不是可以在C++程序中调用过,我没有做过实验,有时间的同学可以试试。在这里我们想要解决的问题就是怎么名称就是:output
这里有两种解决方案:
方法1
#include "stdafx.h"
#include
extern"C"__declspec(dllexport) void output();
void output()
{
using namespace std;
cout << "今天是2018年,10月,8号!!!" << endl;
}
在dllexport 前面加上extern"C" 。注意这种方法只适用于C,C++,(网上说的,我也没试过,你们可以试试。)
方法2
在这里添加一个.def后缀的文件。内容如下:
//这里后面是函数名称
LIBRARY test
EXPORTS
//这里是实现函数。
output
然后重新编译:
这里就会发现函数名称没有被添加别的编译。具体选择哪种用法,看个人选择。后者可能比较麻烦,但是是一种通用的方法。推荐。。
这里新建一个项目,注意,这里我们选择一个项目新建。
第一步,我们要把LIB文件连到这个新的项目中,大家一般都会称这个为隐式调用DLL。
这里第一个,附加库目录:指向你的lib目录。附加依赖项:添加库目录中.lib的名称。
#include "stdafx.h"
__declspec(dllimport) void output();
int main()
{
output();
return 0;
}
这里注意第二行。 类似DLL生成。在这里基本上大功告成,但是编译完成后,你们会发现缺少xxx.dll文件。这里是我们上面只给了lib文件但是没有给出DLL文件在哪里。这里又有两种方法:简单点的就是把DLL文件CP到新的项目的Debug中。但是这样是不是有点low,下面是第二种解决办法。
这种方法直接指向DLL文件所在目录。
这种方法主要就是用windowsAPI来调用DLL,直接丢开LIB文件不用管(具体的.h类怎么处理),这里我也不是很清楚,有了解的同学可以@我。
#include "stdafx.h"
#include
#include
int main()
{
using namespace std;
//定义函数指针
typedef int(*addFun)(int, int);
typedef int(*Subtract)(int, int);
//定义dll文件句柄
HINSTANCE hDll;
addFun add;
Subtract subtract;
//装载dll文件
hDll = LoadLibrary(_T("test.dll"));
//用新名称来更换dll文件中的函数名称。
add = (addFun)GetProcAddress(hDll, "add");
int a = 2;
int b = 3;
cout << add(a, b) << endl;
subtract = (Subtract)GetProcAddress(hDll, "subtract");
cout << subtract(b, a) << endl;
return 0;
}
这种方法很暴力呀,直接可以调用DLL文件,也不用添加一堆依赖项,重要的是,它可以随时释放DLL文件占用的内存。相对于上面那种方式更容易节省内存,有兴趣的同学可以试试。
这篇blog 写了一次入门级别的封库,以及怎么调用我们的库文件。供大家参考学习,也是给自己做个笔记。但是我相信,作为一种保护代码,和简洁代码的方式,是我们每一个C++程序员必须要掌握的。