C#调用C++的DLL,传递参数为double数组
背景
合作方提供了C++制作的DLL,DLL内函数的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);
该函数主要用于计算图像的灰度统计特征,其中,in是灰度图像的路径,hist和value分别是double类型的数组,hist_n和value_n分别是数组的长度,其余参数的含义可以忽略,不重要。
需求
桌面客户端开发语言是C#,要在C#内调用上述DLL中的calHist函数,给定图像的路径,然后得到hist和value这两个数组的结果。
方法
借助指针实现参数传递,C#提供了Marshal类,通过Marshal类中的提供的方法分配内存、传递至DLL进行计算、将数据从非托管内存指针复制到托管数组中、释放内存。
具体实现

在C#内声明函数,对照提供的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方法开辟全局内存

调用DLL
API.calHist(inputImagePath, roiCmin, roiCmax, roiRmin, roiRmax, ref phist,
ref hist_n, step, ref pvalue, ref value_n);

复制数据
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方法
// 将数据从非托管指针复制到托管数组中
// 不要自己操作指针

释放内存
Marshal.FreeHGlobal(pvalue);
Marshal.FreeHGlobal(phist);
// 必须释放指针对应的非托管内存
测试结果



