VSC#搭配C++动态链接库开发OpenCV

VSC++配置OpenCV

C++动态链接与OpenCV环境搭建

创建动态链接库

image

添加环境变量

在用户变量下的Pah中添加以下环境变量

D:\Opencv3.4.6\build\bin

D:\Opencv3.4.6\build\x64\vc15\bin

image

动态链接库添加并配置属性表

在属性管理器下的Debug|x64中添加属性表

image

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

image

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

image

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

image

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

image

另存属性表备用

image

从属性表直接引用OpenCV配置

新建C++动态链接库,编辑代码显示引用报错

image

image

添加现有属性表

image

image

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

image

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#程序生成目录一致

image

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

image

C#程序配置

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

image

image

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-启用本机代码调试

image

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

image

断点命中极为成功

image

posted @ 2025-12-16 02:54  ZHIZRL  阅读(9)  评论(0)    收藏  举报