创建动态库,会生成xxx.dll和xxx.lib两个文件。
1.打开VS2013:
菜单->文件->新建->项目->win32控制台应用程序(选择“Win32项目”亦可),项目名称:DLLGen(名称随意)。
3.创建 头文件DLLGen.h:
包括需要的头文件(例如opencv.hpp)、命名空间(namespace)、特别是要动态调用的函数的声明。
4.创建 源文件DLLGen.cpp:
不要有主函数,只编写你需要动态调用的函数源代码即可(记得包含你的头文件)。
5.创建 源文件dllmain.cpp:(一定要#include
)
下面的dllmain.cpp函数是VS2013自动生成的(当不选空项目时,VS2013自动生成的),直接复制即可。
当但不选空项目,会产生很多其他文件和依赖项,此方法是要建立最纯净的工程。
注意:一定要包含
#include
。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}//end switch
return TRUE;
}//end DllMain
6.创建 源文件Source.def:
创建方式:如下图,选择“代码->模块定义文件(.def)”。
第1行:在引号中,填入你的项目名称(”DLLGen”)即可。
第2行:在EXPORTS的下面,列出准备调用的函数名称,格式:“函数名 @序号”。
LIBRARY "DLLGen"
EXPORTS
Match @1
Locate @2
小提示:我们不必列出函数声明中的所有函数,只列出那些需要调用或开放的函数名即可(这样可以隐藏或封装具体算法)。
7.点击:菜单->生成->生成解决方案;或者 按Ctrl+F5 即可。
当然,编译成功的前提是,你已经配置好项目需用OpenCV或CUDA环境(这里选择的是Release版和x64平台)。
OpenCV的环境搭建,可参见:http://blog.csdn.net/cosmoshua/article/details/72183624
CUDA的环境搭建,可参见:http://blog.csdn.net/cosmoshua/article/details/73332742
输出栏会显示:创建库 DLLGen.lib 和 生成了 DLLGen.dll(注意文件输出的位置)。
8.找到生成的库文件(DLLGen.lib 和DLLGen.dll),将这两个文件和头文件(DLLGen.h),复制到你的目标文件夹(例如F:\Test\DLL)中备用即可。至此,动态库创建完毕!
注意:xxx.lib文件里面有对xxx.dll文件的描述,所以不要对生成的xxx.dll文件改名称,否则lib文件和dll文件无法对应。
调用动态库,会调用xxx.dll、xxx.lib和xxx.h三个文件。
1.打开VS2013:
菜单->文件->新建->项目->win32控制台应用程序(选择“Win32项目”亦可),项目名称:DLLTest。
注意:一定要选择“控制台应用程序”,否则编译时会报错。
error LNK2001: 无法解析的外部符号 WinMain
3.配置调用动态库的环境:
3.1 懒人配置法:
A. 直接将DLLGen.dll、DLLGen.lib和DLLGen.h三个文件,复制到项目DLLTest的目录下。
B.右键点击DLLTest项目->属性->配置属性->链接器->输入->附加依赖项,输入“DLLGen.lib”,点击“确定”即可。
3.2 常规配置法:
A. 将DLLGen.dll、DLLGen.lib和DLLGen.h三个文件,复制到某个文件下备用(例如F:\Test\DLL)。
B. 右键点击DLLTest项目->属性->配置属性->VC++目录:
->包含目录,新建文件夹“F:\Test\DLL”,点击“确定”即可。(主要是告诉编译器DLLGen.h的位置所在)
->库目录,新建文件夹“F:\Test\DLL”,点击“确定”即可。(主要是告诉编译器DLLGen.lib的位置所在)
C.右键点击DLLTest项目->属性->配置属性->链接器->输入->附加依赖项,输入“DLLGen.lib”,点击“确定”即可。
D.配置xxx.dll位置:
VS工程在调用xxx.dll时:
(1). 首先会在工程文件目录中查找xxx.dll。对于简单的工程,可将xxx.dll文件复制到工程目录中(参见“懒人配置法”)。
(2). 若在工程文件目录中找不到,会在C:\Windows\System32中查找。对于常用的xxx.dll,可将其放到C:\Windows\System32中。
(3). 对于常用的xxx.dll,可将xxx.dll所在的目录(例如F:\Test\DLL)添加到Windows系统的环境变量PATH中。(可能需要重启电脑后才能生效)
4.创建 源文件DLLTest.cpp:
A. 包含头文件DLLGen.h:#include "DLLGen.h"
小提示:由于生成DLLGen.dll时,我们只导出了Match和Locate函数。所以调用时,头文件中可以只保留Match和Locate的函数声明。(当然,include和namespace部分不要改。)
B. 配置xxx.lib的补充技巧:
如果不想通过“附加依赖项”(属性->配置属性->链接器->输入->附加依赖项)配置DLLGen.lib
,也可以用预编译语句实现:
在main()函数前,添加 #pragma comment(lib, "DLLGen")
。
添加“附加依赖项”或添加预编译语句
#pragma comment(lib, "xxx")
,这两种配置方法等价,二选一即可。
至此,动态库调用成功!
1.平台问题:x86平台和x64平台编译出来的dll不能混用,否则链接时会报错。错误 1 error LNK2001: 无法解析的外部符号 "bool __cdecl Tracker(class cv::Mat const &,class cv::Mat &,class cv::Rect_
2.如果遇到只生成dll,却未生成lib文件(我在x86平台编译时遇到了,好像xxx.def失效了)。
解决方案:
A.删除xxx.def。
B.修改xxx.h文件:在函数声明前加入一行代码:#define DLL_API __declspec(dllexport)
。
然后,在每个要导出的函数声明前,加上DLL_API
,告诉编译器该函数是要导出的。
参考文献:
http://blog.csdn.net/u010273652/article/details/25514577
http://www.cnblogs.com/TenosDoIt/p/3203137.html