非託管參數為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; // Face Service工作模式
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;
}
}