C# 在C中作为参数传递结构指针#
我需要包含一个.dll,其中包含以下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
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++代码使用的默认打包)。您还可以使用为编组指定一个固定大小的数组 您也不需要C#实现来使用[marshallas(UnmanagedType.ByValArray,SizeConst=16)]
,事实上,对于相当大的数据量,我建议使用类 下面是一个例子: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
有了这些更改,封送员应该为您处理好事情。我会避免使用不安全的
,而是对固定大小的数组使用
。@MatthewWatson然后将此作为回答:)个人,我会使用固定缓冲区,我不会使用[MarshalAs(UnmanagedType.ByValArray,SizeConst=16)]
,因为这样你就必须为项目启用fixed
,然后它会传播到使用该类的所有其他项目。@MatthewWatson是的,我很熟悉它的含义(所有我将这些类型本地化到直接使用它们的任何项目的好理由),再说一次:如果你有更好的方法——这将是一个很好的第二个答案——让我们说我有一个函数,我初始化“MyStruct test_struct”,并将test_struct.data[0]设置为10。如何将其作为指向固定块的指针传递?稍微观察一下:导出为safe
,而myFunc
为extern
,没有告诉它新名称;那只是复制/粘贴的事情吗?因为:这也不会让事情发生。如果我使用类对象指针作为参数(ref对象),程序会崩溃。但我意识到类对象已经是引用,需要按值传递。非常感谢你!mvb\u PutPort