VSC#搭配C++动态链接库开发OpenCV
VSC++配置OpenCV
C++动态链接与OpenCV环境搭建
创建动态链接库

添加环境变量
在用户变量下的Pah中添加以下环境变量
D:\Opencv3.4.6\build\bin
D:\Opencv3.4.6\build\x64\vc15\bin

动态链接库添加并配置属性表
在属性管理器下的Debug|x64中添加属性表

VC++目录中包含目录添加D:\Opencv3.4.6\build\include

VC++目录中库目录添加D:\Opencv3.4.6\build\x64\vc15\lib

链接器-输入-附加依赖项添加opencv_world346d.lib

编辑代码检查环境配置,诺失败可尝试重启VS

另存属性表备用

从属性表直接引用OpenCV配置
新建C++动态链接库,编辑代码显示引用报错


添加现有属性表


观察代码引用是否报错判断是否应用成功

C#配合C++动态链接库调试
编写C++动态链接库
添加OpenCVMethod头文件和C++文件
编写读取图像方法
#pragma once
#ifdef IMAGEPROCESSOR_EXPORTS
#define IMAGEPROCESSOR_API __declspec(dllexport)
#else
#define IMAGEPROCESSOR_API __declspec(dllimport)
#endif
// 定义跨语言的简单数据类型
typedef struct {
int channels;
int width;
int height;
void* ImgDataAddr;
int ImgIndex;
int ImgState;
int ImgType;
int ImgFormat;
} ImgStruct_t;
extern "C" {
IMAGEPROCESSOR_API void ReadImage(const char* FileName, const char* Format, ImgStruct_t& pImgOutput, bool IsWriteData = true);
}
#include "pch.h"
#include "OpenCVMethod.h"
#include"opencv2/opencv.hpp"
void ReadImage(const char* FileName, const char* Format, ImgStruct_t& pImgOutput, bool IsWriteData)
{
//转换为 std::string
std::string imagePath(FileName);
// 使用 OpenCV 读取图像
cv::Mat image = cv::imread(imagePath, cv::IMREAD_UNCHANGED);
// 获取图像的高、宽、通道数
pImgOutput.height = image.rows;
pImgOutput.width = image.cols;
pImgOutput.channels = image.channels();
// 计算图像数据的总大小(字节数)
size_t dataSize = image.total() * image.elemSize();
if (!IsWriteData)return;
// 分配内存并创建 void* 指针
//pImgOutput.ImgDataAddr = malloc(dataSize);
// 将图像数据复制到 void* 指针
memcpy(pImgOutput.ImgDataAddr, image.data, dataSize);
}
修改生成目录,与C#程序生成目录一致

编译C++动态库生成DLL文件

C#程序配置
修改平台统一为x64,移除Any CPU,所有项目配置自动生成 <Platforms>x64</Platforms>


C#调用C++动态链接库的DLL
public interface IVisualOperator
{
/// <summary>
/// 读取图像
/// </summary>
/// <param name="FileName">图像路径</param>
/// <param name="Format">图像格式</param>
/// <param name="pImgOutput">图像数据</param>
/// <param name="IsWriteData"></param>
int ReadImage(string FileName, string Format, ref ImgStruct_t pImgOutput, int IsWriteData = 1);
int FindLine(ImgStruct_t pImgOutput, MeasureROIStruct_t measureROIStruct_t, ref LineStruct_t lineStruct_t);
}
public class OpenCV_DLL : IVisualOperator
{
public int ReadImage(string FileName, string Format, ref ImgStruct_t pImgOutput, int IsWriteData = 1)
{
return OpenCVEncapsulation.ReadImage(FileName, Format, ref pImgOutput, IsWriteData);
}
public int FindLine(ImgStruct_t pImgOutput, MeasureROIStruct_t measureROIStruct_t, ref LineStruct_t lineStruct_t)
{
return OpenCVEncapsulation.FindLine(pImgOutput, measureROIStruct_t, ref lineStruct_t);
}
}
class OpenCVEncapsulation
{
[DllImport("OpenCV_Dll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int ReadImage([In] string FileName, [In] string Format, ref ImgStruct_t pImgOutput, int IsWriteData);
[DllImport("OpenCV_Dll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int FindLine([In] ImgStruct_t pImgOutput, [In] MeasureROIStruct_t measureROIStruct_t, ref LineStruct_t lineStruct_t);
}
//调用方法
visualOperator.FindLine(SourceImgData, measureROIStruct_T, ref lineStruct_T);
C#与C++动态链接库联调
C#启动项目在属性-调试-打开调试启动配置文件UI-启用本机代码调试

C++动态链接库打上断点测试

断点命中极为成功

浙公网安备 33010602011771号