之前有个项目关于图像处理,既用到了opencv,还二次开发了相机提供的动态库。一开始我是用QT写的,然后发现人家只需要我提供一个库函数调用就可以了,但是他是用C#写的。没办法,到处找资料,但是没有找到贴切的。最后自己尝试一下,终于弄好的了。其实比较困难的是我的QT动态库里还要包含另外的一个相机的库、opencv的库,然后还要依赖qt。接下来主要介绍vs2019 opencv qt创建动态库被C#调用的过程,optris相机二次开发的就放在下一篇再讲。

目录

第一步:创建一个QT 的动态库

第二步:QT动态库中引入opencv

第三步:动态库中创建好被调用的函数

第四步:生成动态库并找到这个动态库所有的依赖项

第五步:创建C#项目文件调用qt生成的动态库(最坑的地方)


第一步:创建一个QT 的动态库

如下图新建一个QT动态库,选择Qt Class Library,再命名(不规范不要学)选择路径,接下来会跳出来一个QT的界面,选择好对应的版本,我直接默认即可,通常最后生成Release版本。一路next,finish。最后生成一个默认模板的qt动态库。

第二步:QT动态库中引入opencv

上面是创建动态库的示意,接下来以我之前成功的QT动态库imgdeal_qtdll为例进行接下来的讲解。

首先你应该需要下载好,编译好opencv,创建相应的环境变量,正常项目中能够调用opencv,这个CSDN上有非常多的博客,搜索opencv库即可。

回到这个项目,首先像其他一样,在项目属性管理器中添加好opencv的路径(环境变量中设置的)。点击上方的项目→属性。

然后选择VC++目录,包含目录、库目录中分别中添加好opencv路径,如下图。

接下来点开C/C++→常规→附加包含目录,添加好路径。

链接器→ 输入→附加依赖项,添加opencv,我打算生成Release版本所以只添加不带d的。

最后点击确定就完成了opencv库的引入,只要在项目文件中添加好对应头文件、命名空间,就能正常使用opencv的函数了。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/utils/logger.hpp>
using namespace cv;

第三步:动态库中创建好被调用的函数

imgdQtdll_global.h文件不用动。

imgdeal_Qtdll.h中默认生成的东西不用动,然后添加好你会用到的头文件。重要的是最后两行,创建好这个动态库你想导出,能够被调用的函数,像我这里导出了两个函数。

imgdeal_Qtdll.cpp中默认的模板不用更改,创建你在h文件中定义的想被导出的函数,注意 我是在类外创建的函数,除了两个导出的函数,其他是回调的、被导出函数调用的。

因为会需要用到比较麻烦的回调,按理来说在类内创建函数也行。需要用到的变量我也是直接在cpp文件中进行声明。

第四步:生成动态库并找到这个动态库所有的依赖项

动态库中的函数写好没有问题后,右击解决方案,选择生成/重新生成。

再右击解决方案→在文件资源管理器中打开文件夹,在文件夹中打开x64→Release,可以看到对应环境生成的动态库,dll文件。

然后很多人就直接拿着这个动态库去让C++、或者C#调用,发现不行,C#提示“应用程序中发生了未经处理的异常”、“无法加载xxx:找不到指定的模块”。、

这其实是因为你创建的动态库:第一依赖与Qt的环境,用到了Qt的变量类型;第二是调用了opencv的函数,那么opencv的动态库也要一起放过去。

为了一劳永逸,使用vs自带的dumpbin工具查找你生成的动态库的依赖项。具体可以参考这篇文章

查看dll或exe文件的依赖项——使用vs自带的dumpbin工具

使用上面的工具找到生成动态库的依赖项,如下图所示,可以看到,除了一些公用的库之外,还依赖了QtCore.dllopencv_world454.dllImagerIPC2x64.dll(这个是我相机的动态库),那么我们就需要找到这些dll文件,与生成的动态库一起移动,QtCore.dll就在你安装qt目录下,例如我的是在 D:\app\qt\qt5.12.9\5.12.9\mingw73_64\bin 下面,注意平台要匹配,我是x64下的所以是mingw73_64文件及下面。找到所有依赖的dll文件后,再进行下一步。

第五步:创建C#项目文件调用qt生成的动态库(最坑的地方)

打开vs新建项目,这里我直接新建一个控制台应用进行测试。

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;namespace WindowsFormsApp1
{public partial class Form1 : Form{[DllImport("imgdeal_Qtdll.dll", EntryPoint = "imgdeal", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]public static extern void imgdeal(double leftx, double lefty, double rightx, double righty,  string Path);[DllImport("imgdeal_Qtdll.dll", EntryPoint = "Pixsanp", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]public static extern int Pixsanp();public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){HELLOW();}public void HELLOW(){Pixsanp();Console.WriteLine("helloword");double leftx, lefty, rightx, righty;leftx = 13.625; lefty = 27.667;rightx = 14.583; righty = 27.833;string ImagePath = "D:\\Imager Data\\";imgdeal( leftx,  lefty,  rightx,  righty, ImagePath);}}
}

为啥要说最坑呢?因为C#和C++的数据类型虽然名称一样,但是是完全不同的类型!!比如一个函数imgdeal(),需要传入string类型的参数,但是C++和C#的string完全不是一个东西!!!!没有办法,把C++里面的string改成与C#string对应的wchar_t*格式,然后再如图所示在qt动态库里面转成Qstring。(不要纠结为啥我一定要C++的string!!!!!)

所以在写函数的时候注意数据类型,另外师兄说灵活运用C++中的指针可以更好解决这个问题。

C++:
void imgdeal(double leftx, double lefty, double rightx, double righty, wchar_t* Path);C#:
void imgdeal(double leftx, double lefty, double rightx, double righty,  string Path);
void imgdeal(double leftx, double lefty, double rightx, double righty, wchar_t* Path)
{QString ImagePath = QString::fromWCharArray(Path);dir.setPath(ImagePath);

首次运行一下,肯定运行失败,然后将生成的动态库与所依赖的dll文件,一起复制放在选择的运行环境的文件夹下,再重新运行,即可。

(成功案例超详细保姆级)vs2019 opencv qt创建动态库被C#调用相关推荐

  1. 成功案例超详细-vs2019 opencv qt创建动态库被C#调用

    之前有个项目关于图像处理,既用到了opencv,还二次开发了相机提供的动态库.一开始我是用QT写的,然后发现人家只需要我提供一个库函数调用就可以了,但是他是用C#写的.没办法,到处找资料,但是没有找到 ...

  2. MySQL数据库快速入门到精通(超详细保姆级,建议收藏)这可能是目前最适合你的教程,从基础语法到实例演示。

    前言 此文章旨在为需要掌握快速开发和复习MySQL的同学所准备,您完全可以把此文章当作参考文档来使用,本文将尽量精简,使您快速的理解和掌握语法. 关于MySQL MySQL是一个关系型数据库管理系统, ...

  3. 动态规划27k字超详细保姆级入门讲解——附DP经典线性、区间、二维图、四维8个模型题解

    动态规划27k字超详细保姆级入门讲解 写在前面: 这篇文章是目前为止我写过最长也是最久的文章,前面关于DP的讲解我查阅了大量的博客资料,学习其他博主对DP的理解,也翻阅了很多经典的纸质书籍,同时做了近 ...

  4. JVM-内存与垃圾回收篇!女朋友看了都想当架构师的超详细保姆级笔记!呕心沥血之作!看完还不会你砍我!

    1. JVM与Java体系结构 1.1 Java虚拟机 Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成. JVM平台的各种 ...

  5. 山东大学软件工程应用与实践——GMSSL开源库(一) ——WINDOWS下GMSSL的安装与编译的超详细保姆级攻略

    2021SC@SDUSC GMSSL简介 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全 ...

  6. vscode配置C/C++环境(超详细保姆级教学)

    大一上学期被学长安利了vscode,但是下载安装后不会配置,自己连查带问搞了七八个小时终于配置好了.后面身边很多同学也不会配,都来找我帮忙配,加上之前自己摸索着配的时候感觉网上没有详细又靠谱的教程,所 ...

  7. JwtToken介绍与使用 超详细保姆级教程 内附详细示例代码

    文章目录 一.什么是JWT认证 二.JWT认证的特点 优点: 缺点: 三.JWT的组成 四.JWT代码展示 一.什么是JWT认证 Json web token (JWT),根据官网的定义,是为了在网络 ...

  8. 飞链云版图安全食用指南 AI绘画超详细保姆级新手教程

    非常感谢Jacky为飞链云版图编写的第一篇用户新手教程--飞链云官方! 前言: 在接触飞链云版图(以下简称飞链云AI)之前,笔者曾使用过 sd(stable diffusion)各版本. wAIfu ...

  9. 【微信聊天记录制作词云】超详细保姆级教学!!!(详细步骤+代码)

    简介 还在因各种情侣节日不知道送对方什么礼物而感到苦恼吗?不如试试这个超浪漫的微信聊天词云! 整体思路主要为: 1. 利用模拟器找到备份文件 2. 解密文件并导出文本文件 3. 代码制作词云 前期准备 ...

最新文章

  1. 使用 GNU Libtool 创建库
  2. Policy Optimization-强化学习业界手册
  3. java线程夯住了怎么解决,不明白线程为什么卡住了? 求大神解救
  4. VSCode自定义代码片段4——cli的终端命令大全
  5. 设置go path_Go命令的PATH安全性
  6. Android 轻松实现仿淘宝地区选择
  7. T2 Funcin T1,out T2(T1 arg)
  8. ansible安装与配置文件
  9. java 港澳台手机号码正则表达式
  10. iphone如何显示实时网速和内存空间
  11. 计算机断电无法启动不了系统,电脑突然断电后无法启动怎么回事
  12. Mac键盘突然失灵怎么办?别急,教你打开辅助键盘
  13. A Survey on Conversational Recommender Systems
  14. NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE-论文翻译
  15. php上传文件并存储到mysql数据库的方法
  16. html5微杂志源码,H5制作又一利器:分分钟制作一个H5页面
  17. echarts tooltips 自定义 formatter 显示图例颜色
  18. ie下利用js操作文件及目录
  19. 小白静态路由配置教程,备份接口和缺省路由。
  20. Android性能优化面试题集锦,实战篇

热门文章

  1. h5 关于视频video在微信中的自动播放
  2. 前端常用UI且好用的网站总结
  3. php相册源码无数据库,EasyImage|简单强大无数据库的PHP图床源码
  4. Python3爬虫抓取微信好友数量、性别、以及城市分布等信息。
  5. 什么underlay网络?
  6. 去掉input和button标签的原始边框
  7. 原码运算、反码运算、补码运算和溢出
  8. Linux系统中的以太网连接
  9. element-ui远程搜索框,没有查询条件时显示历史搜索,有查询条件显示符合条件的数据(配合后端)
  10. 如何使用 Cocos 轻松实现汉字临摹?