Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中作为参数传递结构指针#_C#_C++_Pointers_Struct_Parameters - Fatal编程技术网

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

C# 在C中作为参数传递结构指针#,c#,c++,pointers,struct,parameters,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

我需要包含一个.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变量并调用如下函数:

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

然而,这似乎不起作用。函数正在传递一些东西,但不是正确的值,我建议它是指针用法。也许struct*与ref struct不一样。。。有人能解释一下问题是什么吗?

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

不安全结构MyStruct
{
ushort us1,us2;
固定ushort数据[16];
}
这与数组不同,在C#代码中使用起来有点尴尬,但是:这是可能的

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

publicstaticextern intmvb_PutPort(MyStruct*CommData);
这意味着您需要通过以下方式进行呼叫:

fixed(MyStruct*ptr=whateveryouregoingtopass)
{
mvb_输出端口(ptr);
}

您可能需要指定结构的填充(取决于C++代码使用的默认打包)。您还可以使用
[marshallas(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
声明匹配


有了这些更改,封送员应该为您处理好事情。

我会避免使用
不安全的
,而是对固定大小的数组使用
[MarshalAs(UnmanagedType.ByValArray,SizeConst=16)]
。@MatthewWatson然后将此作为回答:)个人,我会使用固定缓冲区,我不会使用
fixed
,因为这样你就必须为项目启用
safe
,然后它会传播到使用该类的所有其他项目。@MatthewWatson是的,我很熟悉它的含义(所有我将这些类型本地化到直接使用它们的任何项目的好理由),再说一次:如果你有更好的方法——这将是一个很好的第二个答案——让我们说我有一个函数,我初始化“MyStruct test_struct”,并将test_struct.data[0]设置为10。如何将其作为指向固定块的指针传递?稍微观察一下:导出为
myFunc
,而
extern
mvb\u PutPort
,没有告诉它新名称;那只是复制/粘贴的事情吗?因为:这也不会让事情发生。如果我使用类对象指针作为参数(ref对象),程序会崩溃。但我意识到类对象已经是引用,需要按值传递。非常感谢你!