C#调用非托管DLL参数传递备忘录
非托管参数为const MyStruct* myStructInstance和Mystruct* myStructInstance的时候,C#程序都可以通过ref MyStruct myStructInstance来传递参数
2,C++,C中的long都为4字节数,转到C#中都为int型
例如
C,C++中的定义
typedef struct HS_RECT
{
long left;
long top;
long right;
long bottom;
}HS_RECT;
放到C#中应为
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct HS_RECT
{
public int left;
public int top;
public int right;
public int bottom;
};
3,结构体转换为指针类型
//定义eyePoint为一个HS_EyePoint结构体
FeatureData.HS_EyePoint eyePoint;
//定义pEye 为一个指向HS_EyePoint的指针
IntPtr pEye = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(FeatureData.HS_EyePoint)) );
//把eyePoint转换为pEye,即让pEye指向eyePoint的地址
Marshal.StructureToPtr(eyePoint, pEye, true);
//程序处理
nRetCode = HS_LocateEye(pbyGrayImage, nImageWidth[0], nImageHeight[0],
ref rcFace, ref eyePoint);
//处理完毕,把指针还原为结构体
eyePoint = (FeatureData.HS_EyePoint) Marshal.PtrToStructure(pEye, typeof(FeatureData.HS_EyePoint));
//释放指针指向的空间
Marshal.FreeCoTaskMem(pFace);
代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace FeatureExtraction
{
public partial class Form1 : Form
{
//调用C DLL 中的函数
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_InitFaceIDSDK", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_InitFaceIDSDK(FeatureData.HS_FACEMODE enMode);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_GetFaceFeatureSize", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_GetFaceFeatureSize();
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_GetImageSize", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_GetImageSize(string strImagePathName, int[] nImageWidth, int[] nImageHeight);
//int __stdcall HS_GetImageSize(const char *strImagePathName, int *nImageWidth, int *nImageHeight);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_GetGrayImageFromFile", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_GetGrayImageFromFile(string strImagePathName, Byte[] pbyOutGrayImage);
//int __stdcall HS_GetGrayImageFromFile(const char *strImagePathName, Byte *pbyOutGrayImage);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_FaceDetection", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_FaceDetection(Byte[] pbyGrayImage, int nImageWidth, int nImageHeight, int nMinFaceSize,
int nMaxFaceSize, ref FeatureData.HS_FaceCandidate pOutFaceCand, int[] nFaceNum);
//int __stdcall HS_FaceDetection(const Byte *pbyGrayImage, int nImageWidth, int nImageHeight, int nMinFaceSize,
// int nMaxFaceSize, HS_FaceCandidate *pOutFaceCand, int *nFaceNum);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_LocateEye", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_LocateEye(Byte[] pbyGrayImage, int nImageWidth, int nImageHeight, ref FeatureData.HS_RECT pFaceRect, ref FeatureData.HS_EyePoint pEyePoint);
//int __stdcall HS_LocateEye(const Byte *pbyGrayImage, int nImageWidth, int nImageHeight,
// const HS_RECT *pFaceRect, HS_EyePoint *pEyePoint);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_FaceExtractionByEyepos", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_FaceExtractionByEyepos(Byte[] pbyGrayImage, int nImageWidth, int nImageHeight, ref FeatureData.HS_EyePoint pEyePoint, Byte[] pbyFeature);
//int __stdcall HS_FaceExtractionByEyepos(const Byte *pbyGrayImage, int nImageWidth, int nImageHeight,
// const HS_EyePoint *pEyePoint, Byte *pbyFeature);
[DllImport("HISIGN_FaceID.dll", EntryPoint = "HS_UninitFaceIDSDK", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int HS_UninitFaceIDSDK();
//int __stdcall HS_UninitFaceIDSDK();
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
int retCODE = GetDone();
}
private int GetDone()
{
FeatureData.HS_FACEMODE enMode; // 人脸识别工作模式
int nRetCode; // 返回值代码
FeatureData.HS_FaceCandidate[] pFaceCand; // 人脸检测候选
int[] nFaceNum = new int[1]; // 检测到的人脸数目
string strImagePath = @"C:\Documents and Settings\kingking\My Documents\My Pictures\me\344.jpg"; // 人脸图像名
int[] nImageWidth = new int[1]; // 图像宽度、高度
int[] nImageHeight = new int[1];
Byte[] pbyGrayImage = null; // 灰度图像缓冲区
FeatureData.HS_EyePoint eyePoint=new FeatureData.HS_EyePoint(); // 眼睛位置
int nFeatSize; // 得到本版本SDK的人脸特征的字节数
Byte[] pbyFeatures = null; // 特征缓冲区
// 初始化SDK
enMode = FeatureData.HS_FACEMODE.HS_Verify;
nRetCode = HS_InitFaceIDSDK(enMode);
if (nRetCode != FeatureData.HISIGN_ERR_NONE)
{
return nRetCode;
}
// 得到人脸特征的字节大小
nFeatSize = HS_GetFaceFeatureSize();
// 从文件中读取人脸图像,将人脸图像转化成灰度图像
nRetCode = HS_GetImageSize(strImagePath, nImageWidth, nImageHeight);
pbyGrayImage = new Byte[nImageWidth[0] * nImageHeight[0]];
nRetCode = HS_GetGrayImageFromFile(strImagePath, pbyGrayImage);
pFaceCand = new FeatureData.HS_FaceCandidate[100]; // 分配人脸检测结果的内存
// 进行人脸检测
nRetCode = HS_FaceDetection(pbyGrayImage, nImageWidth[0], nImageHeight[0], 20,
(nImageWidth[0] >= nImageHeight[0] ? nImageHeight[0] : nImageWidth[0]), ref pFaceCand[0], nFaceNum);
// 对每个检测到的人脸进行眼睛定位
for (int i = 0; i < nFaceNum[0]; ++i)
{
FeatureData.HS_RECT rcFace;
rcFace.left = pFaceCand[i].trueleft;
rcFace.top = pFaceCand[i].truetop;
rcFace.right = pFaceCand[i].trueright;
rcFace.bottom = pFaceCand[i].truebottom;
//IntPtr prcFace = Marshal.AllocCoTaskMem(Marshal.SizeOf(rcFace));
//Marshal.StructureToPtr(rcFace, prcFace, false);
IntPtr pFace = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(FeatureData.HS_RECT)) );
Marshal.StructureToPtr(rcFace, pFace, true);
IntPtr pEye = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(FeatureData.HS_EyePoint)) );
nRetCode = HS_LocateEye(pbyGrayImage, nImageWidth[0], nImageHeight[0],
ref rcFace, ref eyePoint);
//eyePoint = (FeatureData.HS_EyePoint) Marshal.PtrToStructure(pEye, typeof(FeatureData.HS_EyePoint));
Marshal.FreeCoTaskMem(pFace);
Marshal.FreeCoTaskMem(pEye);
// 进行特征提取
pbyFeatures = new Byte[nFeatSize];
nRetCode = HS_FaceExtractionByEyepos(pbyGrayImage, nImageWidth[0],
nImageHeight[0], ref eyePoint, pbyFeatures);
pbyFeatures = null;
//Marshal.FreeHGlobal(prcFace);
}
pbyGrayImage = null;
pFaceCand = null;
// 释放SDK资源
nRetCode = HS_UninitFaceIDSDK();
return nRetCode;
}
}