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;

            }
}



posted on 2008-04-24 09:54  步走高飞  阅读(1376)  评论(2编辑  收藏  举报

导航