我需要在编译时传递一个包含结构数组的结构,这些结构的长度是未知的。
我找到了如何使用IntPtr []数组和Marshal.StructureToPtr使用Marshal.Copy和固定大小的结构数组来制作可变大小的基元数组的示例,但是它使用了MarshalAs(UnamangedType.ByValArray)结构定义需要SizeConst参数。
以下是我正在尝试做的一个示例。在C dll中,我有一个具有正弦波定义的结构
typedef struct sinWave
{
double amp; /* sine wave amplitude */
double t; /* time */
double period; /* oscilation period */
double omega; /* phase angle */
} sinWave;
和一个可以容纳多个波浪的结构
typedef struct sinWaveAdd
{
sinWave *waves; /* array of sine waves */
int len; /* length of the array */
} sinWaveAdd;
使用以下原型
在波叠加函数中使用__declspec( dllexport ) double calculateMult( sinWaveAdd *in )
在c#中,我有一个sinWave结构,它可以自行运行
[StructLayout(LayoutKind.Sequential)]
public class sinWaveStruct
{
public double amp; /* sine wave amplitude */
public double t; /* time */
public double period; /* oscillation period */
public double omega; /* phase angle */
}
public sinWaveStruct(double ampP, double tP, double periodP, double omegaP)
{
amp = ampP;
t = tP;
period = periodP;
omega = omegaP;
}
}
但我真的不知道如何构建更大的结构
[StructLayout(LayoutKind.Sequential)]
public class sinWaveAddClass
{
public IntPtr waves; /* array of sinWaveStruct waves */
public int len; /* length of array */
}
因为我需要波数不恒定。
有没有办法将wave数组分支到sinWaveStruct [],IntPtr或IntPtr []而没有一个恒定大小的数组?
答案 0 :(得分:1)
我将结构声明为struct
。这使得它们成为值类型而不是引用类型。当你想要制作它们的数组时很重要。尤其是sinWave
是blittable。
public struct sinWaveStruct
{
public double amp; /* sine wave amplitude */
public double t; /* time */
public double period; /* oscillation period */
public double omega; /* phase angle */
}
public struct sinWaveAdd
{
public IntPtr waves; /* array of sinWaveStruct waves */
public int len; /* length of array */
}
您导入的功能是:
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern double calculateMult(ref sinWaveAdd in);
然后创建并填充sinWaveAdd
:
sinWaveStruct[] arr = new sinWaveStruct[len];
// populate arr
然后固定数组并获取其地址:
GCHandle arrHandle = GCHandle.Alloc(arr, GCHandleType.Pinned);
try
{
sinWaveAdd in;
in.waves = arrHandle.AddrOfPinnedObject();
in.len = len;
double retval = calculateMult(ref in);
}
finally
{
arrHandle.Free();
}