Unity3D中C#调用C++动态库总结

动态库是用C++和OpenCV写的。

我们可以这样给它分类,

1.普通传值,如下面代码中MotionDetect的第4个参数;

2.传引用,MotionDetect的第3个参数,nNum传进动态库后赋值再传回来;

3.引用传一个结构体,MotionDetect的第2个参数,这里其实是传一个结构体的数组,具体像加ref的传参还真不会;

4.传一个有分配内存的变量,需要用到GCHandle,因为C#是可以自动回收内存的,而GCHandle在这里的作用就是把它的内存空间Pin住,传递给C++动态库后再手动回收资源。


using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class D : MonoBehaviour 
{
	struct Color_32
	{
		public byte r;
		public byte g;
		public byte b;
		public byte a;
	}
	Color_32[]  imageDataResult;
	
	GCHandle pixelsHandle;
	
	[DllImport("MotionDetectionDll")]
	private static extern bool MotionDetect( System.IntPtr colors, Color_32[] imageDataResult, ref int nNum, int nChannels );
	
	void Start()
    {
		imageDataResult = new Color_32[128*128];
	}
	
	void Update () 
	{
		int nNum = 0;
		pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
		bool wfDf = MotionDetect( pixelsHandle.AddrOfPinnedObject(), imageDataResult, ref nNum, 4 );
		pixelsHandle.Free();
	}
}

C++中是这么写的

//头文件中多加个结构体定义
#include "stdafx.h"
struct Color_32
{
	byte r;
	byte g;
	byte b;
	byte a;
};
extern "C" _declspec(dllexport) bool MotionDetect ( char* imageData, Color_32 imageDataResult[], int *nNum, int nChannels );

// CPP文件中
extern "C" _declspec(dllexport) bool MotionDetect ( char* imageData, Color_32 imageDataResult[], int *nNum, int nChannels )
{
	IplImage* imgSrc = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 4);
	if(!imgSrc)
	{
		return false;
	}
	cvSetData( imgSrc, imageData, imgSrc->widthStep );
	
	......
	
	for ( int i=0; i< ......; i++ )
	{
		imageDataResult[i].r = ......;
		imageDataResult[i].g = ......;
		imageDataResult[i].b = ......;
		imageDataResult[i].a = ......;
	}
	
	......
	
	*nNum = 5;
	nChannels = 4;
}


你可能感兴趣的:(Unity3D中C#调用C++动态库总结)