如何编组指向数据数组的指针数组

时间:2019-02-25 17:47:52

标签: c# pinvoke marshalling

我试图在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。谁能给我一个提示,我在这里缺少什么?

0 个答案:

没有答案