C#調用C++、Opencv的代碼可以通過托管和非托管兩種形式
非拖管的形式即是采用[DllImport]的形式,這種形式只能調用的C++的函數,
托管的形式用的是ref,可以調用C++類中的方法
首選介紹下非托管的形式:
一、無參數傳遞下的非托管形式
(1).C++中建立“win32項目”為dll格式應用程序
(2).新建cpp程序add.cpp
代碼如下:
extern "C" _declspec(dllexport) int add2(int x,int y)
{
return x+y;
}
(3).編譯,將生成dll程序(debug目錄下 )
(4).C#建立控制台應用程序
代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; //一定得有
namespace CSDll
{
class Program
{
[DllImport("Dll2.dll",EntryPoint="add2",ExactSpelling=true,CallingConvention=CallingConvention.Cdecl)]
public static extern int add2(int a,int b);
static void Main(string[] args)
{
Console.WriteLine(add2(1, 2));
Console.Read();
}
}
}
(5).C++生成的dll一定要放在C#的bin目錄下的debug中
二、傳遞opencv中的Mat圖像
(1)C++ 工程下建立“win32項目”應用程序的dll
(2)創建cpp,代碼如下:
#define DLL_API extern "C" _declspec(dllexport)
#include <opencv2\opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <cv.h>
using namespace cv;
DLL_API uchar * _stdcall run1(char* filename, int & width, int & height, int & step )
{
IplImage* uu = cvLoadImage(filename);
IplImage* dst1 = cvCreateImage(cvSize(uu->width,uu->height),8,1);
cvCvtColor(uu,dst1,CV_RGB2GRAY);
Mat ss(dst1);
uchar * data = new uchar[dst1->height*dst1->width];
data= ss.data;
width = ss.size().width;
height = ss.size().height;
step = ss.step;
return data;
}
(3)編譯,生成dll,並將dll放在C#所建工程的bin->debug目錄下
(5)C#工程下創建窗體應用程序
首先傳遞C++中的彩色圖,代碼如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ImageCS2
{
public partial class Form1 : Form
{
[DllImport("ImageCPP.dll")]
public static extern IntPtr run1(string a, out int width, out int height, out int step);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string filename;
OpenFileDialog op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
filename = op.FileName;
int width, height, step;
IntPtr dst = run1(filename, out width, out height, out step);
Bitmap img = new Bitmap(width, height, step, System.Drawing.Imaging.PixelFormat. Format24bppRgb, dst);
pictureBox1.Image = img;
}
}
}
}
(6) C++傳遞灰度圖,在C#中的代碼略有差別,代碼如下:
[DllImport("raildetection.dll")]
public static extern IntPtr run1(string a , out int width, out int height, out int step);
private void button1_Click(object sender, EventArgs e)
{
string filename;
OpenFileDialog op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
filename = op.FileName;
int width, height, step;
IntPtr dst = run1(filename,out width,out height, out step);
Bitmap img = new Bitmap(width, height, step, <strong>System.Drawing.Imaging.PixelFormat.Format8bppIndexed</strong>,dst);
<strong>img.Palette = CvToolbox.GrayscalePalette;</strong>
pictureBox1.Image = img;
}
}
public static class CvToolbox
{
// #region Color Pallette
/// <summary>
/// The ColorPalette of Grayscale for Bitmap Format8bppIndexed
/// </summary>
public static readonly ColorPalette GrayscalePalette = GenerateGrayscalePalette();
private static ColorPalette GenerateGrayscalePalette()
{
using (Bitmap image = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
{
ColorPalette palette = image.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
return palette;
}
}
}
三、托管形式調用C++中的代碼:
(1)C++工程下建“win32項目”應用程序的dll
(2)建頭文件:factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class factory
{
public:
void show();
};
#endif
(3)建CPP factory.cpp
#include"factory.h"
#include<opencv2/opencv.hpp>
using namespace cv;
void factory::show()
{
Mat img=imread("E://Image//1.jpg");
imshow("src",img);
waitKey(0);
}
(4)建頭文件clrClass.h
#pragma once
#include"factory.h"
public ref class clrClass
{
public:
clrClass(void);
~clrClass(void);
int member;
void showImage();
private:
factory *clrFac;
};
(5)建CPP clrClass.cpp
#include"clrClass.h"
#include"factory.h"
clrClass::clrClass(void)
{
clrFac=new factory();
}
clrClass::~clrClass(void)
{
}
void clrClass::showImage()
{
clrFac->show();
}
(6)使用C++托管類進行封裝。新增clrClass類。並且右擊C++項目->屬性->配置屬性->公共語言運行時支持->公共語言運行時支持(、\clr),然后進行編譯生成DLL。托管形式不是將生成的dll放在C#項目工程的bin->debug目錄下,使用方法后面介紹
(7)C#創建控制台應用程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace gg2
{
class Program
{
[STAThread]
static void Main(string[] args)
{
clrClass clr = new clrClass();
clr.showImage();
}
}
}
(8)右擊C#項目中的引用,將生成的dll添加在引用中,就可以使用C++的類方法了