动态库是用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(); } }
//头文件中多加个结构体定义 #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; }