我试图在C#项目中使用外部本机库,但是我很难用一种特定的方法读取多个数据数组。 方法签名如下:
short WINAPI cnc_sdtreadsmpl(short *stat, long datanum, ODBSD *sampledata);
参数说明如下:
stat [out]:指定指向存储数据读取状态的变量的指针。
datanum [in]: 指定要读取的采样数据数。 (指定八个或更多的值。) 每8个字单元执行一次读取过程。因此,请为此值指定8的倍数。
sampledata [out]:指定指向ODBSD结构数组的指针 存储采样数据。按以下顺序获取采样数据 由cnc_sdtsetchnl函数设置的通道。的结构 ODBSD如下:
typedef struct odbsd {
unsigned short *chadata; /* Pointer to sampling data */
long *count; /* Pointer to reading number */
} ODBSD;
为采样数据准备缓冲区,为采样数据准备缓冲区。 实际读取的数据数。并且每个指针都设置为ODBSD 结构体。准备与通道数量相同的ODBSD结构 数组。并指定此数组指向该参数的顶部指针。 功能正常执行后,实际读取次数 每个通道中的数据都以* count为单位。
据我了解,我需要一个指向数据数组的指针数组。 我尝试了以下方法:
public static extern short cnc_sdtreadsmpl(out short stat, int datanum,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] [In, Out] ODBSD[]
sampledata);
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public unsafe class ODBSD
{
public short* data;
public IntPtr count;
}
public class SamplingData
{
public short[] Data { get; set;}
public int Count { get; set; }
}
public unsafe static short Test(SamplingData[] sampledata, ODBSD[] odbsd, int channelNo, out short stat, int datanum)
{
stat = 0;
if (channelNo >= sampledata.Length)
{
var ret = cnc_sdtreadsmpl(out stat, datanum, odbsd);
return ret;
}
else
{
fixed (short* data = &sampledata[channelNo].Data[0])
{
odbsd[channelNo] = new ODBSD();
odbsd[channelNo].data = data;
odbsd[channelNo].count = new IntPtr();
return Test(sampledata, odbsd, channelNo + 1, out stat, datanum);
}
}
}
var odbsd = new ODBSD[8];
var sampling = new SamplingData[8];
for (int i = 0; i < sampling.Length; i++)
{
sampling[i] = new SamplingData() { Data = new short[1360] };
}
Test(sampling, odbsd, 0, out stat, 1360);
我不了解的第一件事是,如果我使用长度为8的ODBSD数组调用cnc_sdtreadsmpl,则会得到一个 System.Runtime.InteropServices.MarshalDirectiveException“无法编组参数#3 ':数组大小控制参数索引超出范围。” 仅当我删除SizeParamIndex或将其设置为值<= 3时,才会引发此异常。
我删除SizeParamIndex,得到一个 System.AccessViolationException:“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”
我尝试了一些其他方法来实现此目的,但是我总是得到System.AccessViolationException。谁能给我一个提示,我在这里缺少什么?