用VS2013生成和调用DLL库 for OpenCV

创建DLL动态库的方法

创建动态库,会生成xxx.dll和xxx.lib两个文件。

1.打开VS2013:
菜单->文件->新建->项目->win32控制台应用程序(选择“Win32项目”亦可),项目名称:DLLGen(名称随意)。
这里写图片描述

2.应用程序类型:DLL;附加选项:空项目。
这里写图片描述

3.创建 头文件DLLGen.h:
包括需要的头文件(例如opencv.hpp)、命名空间(namespace)、特别是要动态调用的函数的声明。
这里写图片描述

4.创建 源文件DLLGen.cpp:
不要有主函数,只编写你需要动态调用的函数源代码即可(记得包含你的头文件)。
这里写图片描述

5.创建 源文件dllmain.cpp:(一定要#include<windows.h>
下面的dllmain.cpp函数是VS2013自动生成的(当不选空项目时,VS2013自动生成的),直接复制即可。
当但不选空项目,会产生很多其他文件和依赖项,此方法是要建立最纯净的工程。

注意:一定要包含#include<windows.h>

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include <windows.h>
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

扫描二维码关注公众号,回复: 128442 查看本文章

输出栏会显示:创建库 DLLGen.lib 和 生成了 DLLGen.dll(注意文件输出的位置)。
这里写图片描述

8.找到生成的库文件(DLLGen.lib 和DLLGen.dll),将这两个文件和头文件(DLLGen.h),复制到你的目标文件夹(例如F:\Test\DLL)中备用即可。至此,动态库创建完毕!

注意:xxx.lib文件里面有对xxx.dll文件的描述,所以不要对生成的xxx.dll文件改名称,否则lib文件和dll文件无法对应。


调用DLL动态库的方法

调用动态库,会调用xxx.dll、xxx.lib和xxx.h三个文件。

1.打开VS2013:
菜单->文件->新建->项目->win32控制台应用程序(选择“Win32项目”亦可),项目名称:DLLTest。

2.应用程序类型:控制台应用程序;附加选项:空项目
这里写图片描述

注意:一定要选择“控制台应用程序”,否则编译时会报错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"),这两种配置方法等价,二选一即可。

这里写图片描述

5.按Ctrl+F5运行即可。运行效果图:
这里写图片描述

如果提示“计算机中丢失DLLGen.dll”,说明xxx.dll的位置配置有误,参见“配置xxx.dll位置”部分。
这里写图片描述

至此,动态库调用成功!

后记

1.平台问题:x86平台和x64平台编译出来的dll不能混用,否则链接时会报错。错误 1 error LNK2001: 无法解析的外部符号 "bool __cdecl Tracker(class cv::Mat const &,class cv::Mat &,class cv::Rect_<int> &,int (&)[4])"

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

猜你喜欢

转载自blog.csdn.net/cosmoshua/article/details/73927718
今日推荐