C#調(diào)用C++的DLL,傳遞參數(shù)為double數(shù)組
背景
合作方提供了C++制作的DLL,DLL內(nèi)函數(shù)的C++聲明如下
extern "C" __declspec(dllexport) void __stdcall calHist(
? ? char *in, int roiCmin, int roiCmax, int roiRmin, int roiRmax, double *&hist,
? ? int *hist_n, int hist_size, double *&value, int *value_n);
該函數(shù)主要用于計算圖像的灰度統(tǒng)計特征,其中,in是灰度圖像的路徑,hist和value分別是double類型的數(shù)組,hist_n和value_n分別是數(shù)組的長度,其余參數(shù)的含義可以忽略,不重要。
需求
桌面客戶端開發(fā)語言是C#,要在C#內(nèi)調(diào)用上述DLL中的calHist函數(shù),給定圖像的路徑,然后得到hist和value這兩個數(shù)組的結(jié)果。
方法
借助指針實現(xiàn)參數(shù)傳遞,C#提供了Marshal類,通過Marshal類中的提供的方法分配內(nèi)存、傳遞至DLL進行計算、將數(shù)據(jù)從非托管內(nèi)存指針復制到托管數(shù)組中、釋放內(nèi)存。
具體實現(xiàn)

在C#內(nèi)聲明函數(shù),對照提供的C++聲明即可,具體為
????????????[DllImport("GrayStatistics.dll", EntryPoint = "calHist")]?
????????????public static extern void calHist(
????????????????string i, int roiCmin, int roiCmax, int roiRmin, int roiRmax,?ref IntPtr hist,?
????????????????ref int hist_n,?int hist_size,?ref IntPtr value, ref int value_n);? ??

初始化變量
????????????string inputImagePath = @"F:\DataSets\MSTAR\TEST\2S1\HB14931.jpeg";
? ? ? ? ? ? int roiCmin = 50;
? ? ? ? ? ? int roiCmax = 70;
? ? ? ? ? ? int roiRmin = 50;
? ? ? ? ? ? int roiRmax = 70;
? ? ? ? ? ? int step = 1;
? ? ? ? ? ? int hist_n = 256 * 4;
? ? ? ? ? ? int value_n = 8;
? ? ? ? ? ??IntPtr phist = Marshal.AllocHGlobal(hist_n * sizeof(double));
? ? ? ? ? ? IntPtr pvalue = Marshal.AllocHGlobal(value_n * sizeof(double));
????????????// 務必使用Marshal提供的AllocHGlobal方法開辟全局內(nèi)存

調(diào)用DLL
????????????API.calHist(inputImagePath, roiCmin, roiCmax, roiRmin, roiRmax, ref phist,?
??????????????????????????????ref hist_n, step, ref pvalue, ref value_n);

復制數(shù)據(jù)
????????????double[] value = new double[value_n];
? ? ? ? ? ? double[] hist = new double[hist_n];
? ? ? ? ? ? Marshal.Copy(pvalue, value, 0, value_n);
? ? ? ? ? ? Marshal.Copy(phist, hist, 0, hist_n);
????????????// 盡量使用Marshal類提供的Copy方法
????????????// 將數(shù)據(jù)從非托管指針復制到托管數(shù)組中
????????????// 不要自己操作指針

釋放內(nèi)存
? ? ? ? ? ? Marshal.FreeHGlobal(pvalue);
? ? ? ? ? ? Marshal.FreeHGlobal(phist);
????????????// 必須釋放指針對應的非托管內(nèi)存
測試結(jié)果

