C#调用C++ dll 总结 内含(opencv)

一直都想搞搞C#调用C++DLL,一直没有时间或搞的时候不成功。今天终于成功了写这篇文章纪念一下顺便总结一下,以防自己忘记。

C#调用C++的方式分为两种:-是非托管的方式进行调用;二是采用托管的方式进行调用。下面针对这两种情况作一简单介绍,理解不到位的地方请各位大牛多多指教。以下工作都是在vs2010上面进行的。

  首先在vs2010新建项目选择win32应用程序,并设置为DLL,如下图所示:

下面先将如何使用非托管类调用C++dll。

在MyDLL.cpp中输入以下代码:

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
 extern "C" __declspec(dllexport) void Show()  
 {  
  IplImage *img = cvLoadImage("1.jpg");
     cvNamedWindow("Image:",1);
     cvShowImage("Image:",img);
     cvWaitKey();
     cvDestroyWindow("Image:");
     cvReleaseImage(&img);
     return ;
 }

extern "C"外部声明,表示函数和变量是按照C语言的方式编译和链接的。

_decspec(dllexport)的目的是为了将对应的函数放入到DLL动态库中。

extern "C" _declspec(dllexport)的目的是为了使用DllImport调用非托管C++的DLL文件。因为使用DllImport只能调用由C语言函数做的DLL。

生成会在项目所在文件夹的Realease里面找到所生成的dll.

新建一个C#控制台应用程序,将上文所生成的DLL拷贝到C#应用程序的bin里面然后应用如下方式进行调用:

[DllImport(“ COM DLL path/file ”)] 
extern static int FunctionName(byte param1, ushort param2)

具体调用的时候在参数传递的过程中会遇到问题,具体解决方式见(http://www.cnblogs.com/82767136/articles/2517457.html)。

下面接着讲如何使用托管类调用C++生成的DLL本人经实验验证得知如果将C++的类函数生成DLL函数再用C++托管类封装相对复杂。因此本人提出以下建议:C++函数-》托管类封装-》C#调用的形式进行。下面简单的来介绍一下。

首先在前面的MyDLL项目中添加Functions.h头文件和Functions.cpp源文件实现利用opencv库输出显示图片。

在Functions.h中

void show();

在Functions.cpp中

#include "stdafx.h"
#include "Functions.h"
#include <opencv2\opencv.hpp>


using namespace cv;
void show()
{
Mat img = imread("lena.jpg");


imshow("src",img);
waitKey(0);
}

使用C++托管类进行封装。新增clrClass类。并且点击“解决方案”中的项目MyDLL->属性->配置属性->公共语言运行时支持->公共语言运行时支持(、\clr)。在clrClass.h中有如下代码:

#pragma once
public ref class clrClass
{
public:
clrClass(void);


int member;


void showImage();


};

在clrClass.cpp中

#include "StdAfx.h"
#include "clrClass.h"
#include "Functions.h"

clrClass::clrClass(void)
{
}
void clrClass::showImage()
{
show();
}

生成,在本人选择Release的情况下生成的DLL在Release目录下;新建C#控制台程序,添加引用->浏览->选择生成的DLL添加。在Program.cs中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication1
{
  
    class Program
    {
        
        static void Main(string[] args)
        {
            clrClass ClrCLass = new clrClass();
            ClrCLass.showImage();
        }
    }
}

本人选择Release的情况下,将图片放在C#应用程序的Release中,运行结果如下:


整个过程结束。

参考文献:

http://wenku.baidu.com/view/6accbfff9b89680203d8256b.html

http://www.cnblogs.com/82767136/articles/2517457.html

http://blog.csdn.net/caowei880123/article/details/6387839

http://blog.sina.com.cn/s/blog_52284fb501012bda.html




要在C#调用C++编写的OpenCV dll,可以使用Platform Invoke(P/Invoke)技术。下面是一个简单的示例,演示如何在C#调用C++编写的OpenCV dll: 1. 创建一个新的C#控制台应用程序。 2. 在项目文件夹中创建一个名为“opencv”的子文件夹。 3. 将OpenCV dll文件复制到该子文件夹中。 4. 在Visual Studio中打开项目,并添加以下代码: ```C# using System; using System.Runtime.InteropServices; class Program { [DllImport("opencv\\opencv_core320.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr cvCreateImage( [MarshalAs(UnmanagedType.Struct)] CvSize size, int depth, int channels); static void Main(string[] args) { // 创建一个256x256的8位单通道图像 var size = new CvSize(256, 256); var image = cvCreateImage(size, 8, 1); // 在控制台中输出图像信息 Console.WriteLine("Image created: {0}x{1}, depth={2}, channels={3}", size.Width, size.Height, 8, 1); Console.ReadKey(); } } [StructLayout(LayoutKind.Sequential)] public struct CvSize { public int Width; public int Height; public CvSize(int width, int height) { Width = width; Height = height; } } ``` 上面的代码创建了一个256x256的8位单通道图像,并在控制台中输出了图像信息。 在上面的代码中,我们使用DllImport属性来指定要导入的OpenCV dll的名称和调用约定。在本例中,我们使用Cdecl调用约定。 我们还定义了一个结构体CvSize,用于传递图像大小参数。在C++中,CvSize结构体定义在opencv_core.hpp头文件中。我们在C#中重新定义了这个结构体,以便我们可以在C#中使用它来传递参数。 需要注意的是,由于C++C#使用不同的内存管理机制,因此您需要确保在C#中正确处理从C++返回的指针。在本例中,我们使用IntPtr类型来表示从C++返回的指针,并使用Marshal类中的相关方法来管理它们。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值