动态库是用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;
}