C#调用C++代码,以OpenCV为例

前言

使用C#调用C++代码是一个很常见的需求,因此本文以知名的C++机器视觉库OpenCV为例,说明在C#中如何通过使用P/Invoke(平台调用)来调用C++代码。只是以OpenCV为例,实际上在C#中使用OpenCV可以使用OpenCVSharp这个项目,这是一个很优秀的项目,GitHub地址:https://github.com/shimat/opencvsharp。

image-20241223143622622

但是也有时候确实有需要调用C++代码的情况,因此大概知道应该怎么实现也是很有必要的,其他的C++库也是类似的方法。

下载安装OpenCV并生成DLL文件

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,由Intel公司于1999年开始开发,并由 Willow Garage 继续维护。它支持多种编程语言,包括 Python、C++ 和 Java,可以在 Windows、Linux、MacOS、Android 和 iOS 等多个平台上运行。OpenCV 包含了各种图像处理和计算机视觉算法,可以用于人脸检测、物体识别、图像分割、特征提取、图像转换、相机标定等任务,应用领域广泛,例如安全监控、医疗图像分析、人机交互、AR/VR、工业检测等。OpenCV的高效性和灵活性使其成为计算机视觉研究和开发领域的首选工具之一。无论是学术研究还是工业应用,OpenCV都提供了强大的支持。目前,OpenCV 已经成为全球最流行的计算机视觉库之一,拥有庞大的开发者社区,并不断地推出新版本以支持最新的计算机视觉算法和技术。对于计算机视觉初学者来说,学习和使用 OpenCV 可以获得大量的资源和支持,对于有经验的研究者和开发人员来说,OpenCV 也是非常有价值的工具。

进入官网,官网地址:https://opencv.org/releases/。

下载最新的版本:

image-20241223144221041

安装完成之后,设置环境变量:

image-20241223144400194

使用VS2022创建一个新的C++空项目:

image-20241223144540506

添加一个头文件与源文件。

在头文件中写入:

#pragma once
extern "C" __declspec(dllexport) void DisplayGrayImage(const char* imagePath);

在源文件中写入:

#include <opencv2/opencv.hpp>
#include <iostream>
#include"test.h"

void DisplayGrayImage(const char* imagePath) {
    // 1. 读取图像
    cv::Mat image = cv::imread(imagePath);
    if (image.empty()) {
        std::cerr << "无法读取图像,请检查文件路径: " << imagePath << std::endl;
        return;
    }

    // 2. 灰度转换
    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);

    // 3. 显示原图和灰度图
    cv::namedWindow("原图", cv::WINDOW_NORMAL);
    cv::imshow("原图", image);

    cv::namedWindow("灰度图", cv::WINDOW_NORMAL);
    cv::imshow("灰度图", gray);

    // 等待用户按键
    cv::waitKey(0);

    // 释放资源
    cv::destroyAllWindows();
}
int main() {
    // 调用函数,传入图片路径
    DisplayGrayImage("D:\\狗狗.jpg");
   
    return 0;
}

现在会发现有很多错误,如下所示:

image-20241223145123078

右键项目,点击属性:

image-20241223145224725

在包含目录中包含

D:\Learning\OpenCV\opencv\build\include

D:\Learning\OpenCV\opencv\build\include\opencv2

在库目录中包含

D:\Learning\OpenCV\opencv\build\x64\vc16\lib

设置完成之后,如下所示:

image-20241223150157809

点击链接器——输入

D:\Learning\OpenCV\opencv\build\x64\vc16\lib\opencv_world4100d.lib

如下所示:

image-20241223150418678

debug对应的是opencv_world4100d.lib,release对应的是opencv_world4100.lib。

现在会发现之前的报错已经消失了。

如下所示:

image-20241223150535592

点击看是否能重新运行:

image-20241223150623062

现在需要导出C++的DLL文件。

右键项目,点击属性,将配置类型修改为动态库,如下所示:

image-20241223150841733

重新生成解决方案:

image-20241223151030585

生成了一个DLL文件:

image-20241223151111138

创建C#控制台项目,并调用C++的DLL文件

创建一个C#控制台项目,测试代码如下所示:

image-20241223151355886

using System.Runtime.InteropServices;

class Program
{  
    [DllImport("Project2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern void DisplayGrayImage(string imagePath);

    static void Main()
    {
        DisplayGrayImage("D:\\狗狗2.jpg");
    }
}

运行查看效果,如下所示:

image-20241223151455653

因为要记住,第一步肯定是要把DLL文件复制过来,如下所示:

image-20241223151659508

再次运行,效果如下所示:

image-20241223151811512

以上就是C#通过P/Invoke(平台调用)来调用C++代码的一个简单示例,希望对你有所帮助。

C#调用C++OpenCV库,通常需要借助一些跨语言交互技术,如P/Invoke(Platform Invocation Services),它是.NET框架提供的一种机制,允许C#程序直接调用底层的C/C++函数。以下是基本步骤: 1. **包含头文件**:首先,在C#项目中,你需要添加OpenCVC++库的头文件,如`opencv2/objdetect.hpp`等。 2. **声明DllImport**:使用`DllImport("opencv_core450.dll" // 根据实际版本替换)`等类似注解,指定调用的DLL文件和函数名称。 3. **定义函数原型**:对C++中的函数进行C#风格的定义,包括返回类型、输入参数等。 ```csharp [DllImport("opencv_core450.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr cvLoadImage(string filename, int flags); ``` 4. **转换指针和数据结构**:OpenCV的数据结构可能不是.NET认可的数据类型,需要通过unsafe代码块进行转换。 5. **释放资源**:在不再使用OpenCV资源后,记得调用相应的释放函数,如`cvReleaseImage()` 6. **错误处理**:因为C++ API可能会抛出异常,你需要捕获并处理这些异常。 示: ```csharp using System; using System.Runtime.InteropServices; unsafe class Program { [DllImport("opencv_core450.dll")] public static extern IntPtr cvLoadImage(string filename, int flags); [DllImport("opencv_core450.dll")] public static extern void cvReleaseImage(IntPtr img); public static void Main() { try { IntPtr img = cvLoadImage("image.jpg", 0); // 现在你可以像操作C++的img那样操作它 if (img != IntPtr.Zero) { // 使用OpenCV的其他功能... cvReleaseImage(img); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值