在C#中将结构指针作为参数传递

时间:2020-08-26 07:59:12

标签: c# c++ pointers struct parameters

我需要包含一个.dll,其中包含以下C / C ++函数原型和结构定义:

typedef struct
{
    unsigned short us1;
    unsigned short us2;
    unsigned short data[16];
} myStruct;
int myFunc(myStruct *MYSTRUCT);

要使用此功能,我创建了一个新的类:

static class DLL
{
public struct MyStruct
    {
     public ushort us1;
     public ushort us2; 
     public ushort[] data;
     public PDPORT(ushort[] temp1, ushort temp2, ushort temp3)
     {
         us1 = temp2;
         us2 = temp3;
         data = temp1;
     }
    };
    [DllImport("PDL65DLL.dll")]
    public static extern int mvb_PutPort(ref MyStruct CommData);
}

在我的主类中,我初始化struct变量并像这样调用Function:

    DLL.MyStruct communicationData = new DLL.MyStruct(new ushort[16], new ushort(), new ushort());
             DLL.MyFunc( ref communicationData);

但是,这似乎不起作用。该函数传递了一些东西,但没有传递正确的值,我建议它与指针用法有关。也许struct *与ref struct不同...有人可以解释问题所在吗?

2 个答案:

答案 0 :(得分:2)

您可能需要指定结构的打包(取决于C ++代码使用的默认打包)。您还可以为编组指定一个固定大小的数组,以使用[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]

您也不需要C#实现来使用struct,实际上,对于相当大的数据量,我建议您使用类。

这是一个例子:

[StructLayout(LayoutKind.Sequential, Pack=4)]
public sealed class MyStruct
{
    public ushort   us1;
    public ushort   us2;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public ushort[] data;

    public MyStruct(ushort[] temp1, ushort temp2, ushort temp3)
    {
        us1  = temp2;
        us2  = temp3;
        data = new ushort[16];
        Array.Copy(temp1, data, Math.Min(temp1.Length, data.Length));
    }
}

请注意构造函数如何确保数组的大小正确。您必须始终确保数组的大小与SizeConst声明相匹配。

有了这些更改,Marshaller应该为您做好事。

答案 1 :(得分:1)

C / C ++结构更像是“固定缓冲区”:

    unsafe struct MyStruct
    {
        ushort us1, us2;
        fixed ushort data[16];
    }

这与数组不同,在C#代码中使用起来有点尴尬,但是:有可能。

我不确定100%,但是相信您还应该在P / Invoke层中使用非托管指针:

public static extern int mvb_PutPort(MyStruct* CommData);

这意味着您需要通过以下方式调用它:

fixed (MyStruct* ptr = whateverYouWereGoingToPass)
{
    mvb_PutPort(ptr);
}