网络上关于vs生成dll的教程很多,解决方案繁杂,令人眼花缭乱,踩坑后推荐几篇不错的教程,亲自测试可以通过的,我的调试环境是vs2015 enterprise版+win10+opencv3.4.1。
教程1:最简单的DLL生成与调用教程:作者采用了声明类进行打包的方法来调用。
https://blog.csdn.net/dearKundy/article/details/73331514
教程2:进阶的DLL生成与调用教程,包含了opencv第三方lib和dll的调用与打包,生成的DLL可独立于opencv环境运行。采用的是打包函数的方法,本人推荐这种方法,比较简单易懂。
https://blog.csdn.net/hit2015spring/article/details/52624985
https://blog.csdn.net/sinat_33690776/article/details/68951774
教程3:教程2中采用了静态调用方法,且没有给出多个函数的导出声明,于是我参考教程3完成了多函数导出声明与动态调用。
https://blog.csdn.net/liu_matthew/article/details/55804710
将一个基于opecv的图像超分辨率程序打包成DLL,并测试。接口传入的参数是Mat格式的图像,结果是imshow超分辨率后的图像。
1. 创建无导出符号的dll空项目;
2. 然后就是将之前写的函数代码复制到源文件中的Bleed.cpp中,其它两个cpp不要管。
复制完毕后,点开Bleed.cpp然后对要调用的函数前面加上__declspec(dllexport),如图中所示:
int Bleeding(Mat srcImage) 变为__declspec(dllexport) int Bleeding(Mat srcImage)
作为导出函数声明。
3. 建立源文件Source.def
添加->新建->visual C++ ->模块定义文件(.def)
LIBRARY "Bleed"
EXPORTS
Bleeding
- 在此文件第一行引号中填你的项目名称即可,EXPORTS下面列出要生成的函数名称,若有多个导出函数,则 格式:“名称 @序号”)如:
LIBRARY "DLLGenerator"
EXPORTS
Add @1
Mul @2
这个例子导出了Add和Mul两个函数。
4. 然后在右键点生成解决方案。
在工程目录下会发现生成的Bleed.dll和Bleed.lib文件。
DLL的调用可分为动态调用和静态调用两种,静态调用以来.h,.lib以及.dll文件,而动态调用仅需要dll文件。先讲下如何静态调用DLL:
1. 在项目管理器里,右键单击解决方案,添加/新建项目C++/Win32控制台应用程序,命名。选择没有预编译头。
2. 添加测试代码
在源文件的test_Bleed.cpp添加以下内容
// test_Bleed.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
using namespace std;
#pragma comment(lib, "Bleed.lib") //调用dll文件时候必须用到的
void Bleeding(); //对刚才写好的处理函数进行声明
//主函数
int main()
{
Bleeding();
return 0;
}
3. 生成解决方案,现在肯定是很多错误;
4.将dll和lib文件拷贝到debug文件夹下,与exe文件是同一个文件夹,另外,之前dll引用的文件也都复制到现在这个项目的与cpp同一文件夹下;
5.右键项目名字选择属性,->配置属性->VC++目录->常规-库目录,选择你放置了lib的debug文件夹。
->配置属性->链接器-输入-附加依赖项-编辑加入lib的文件名(全名包含后缀)-确认
6.生成,运行即可
4.动态调用DLL
1. 删掉静态调用时配置的lib和链接器选线: 删除:右键项目名字选择属性,->配置属性->VC++目录->常规-库目录,选择你放置了lib的debug文件夹。
删除:配置属性->链接器-输入-附加依赖项-编辑加入lib的文件名(全名包含后缀)-确认
2. 在源文件中test_dll.cpp添加以下代码:#include "stdafx.h"
using namespace cv;
using namespace std;
typedef int(Dllfun)(Mat);
int _tmain(int argc, _TCHAR argv[])
{
Dllfun Bleed;
HINSTANCE hInst = LoadLibrary(L"Bleed.dll");
if (!hInst)
{
printf(“加载dll失败!\n”);
}
Bleed = (Dllfun)GetProcAddress(hInst, “Bleeding”);
Mat srcImage = imread("E:\\JMCpp\\000024.jpg");
if (!srcImage.data)
return -1;
Bleed(srcImage);
::FreeLibrary(hInst);
return 0;
} 因为测试程序使用了opencv的imread函数,所以#include了opencv的库,若不适用imread,DLL可以脱离opencv使用。