2014-03-28 66 views
0

我需要在編譯時傳遞一個包含未知長度的結構數組的結構。對嵌套在結構中的可變尺寸的結構數組進行編組

我發現如何使用一個IntPtr []數組和Marshal.StructureToPtr,但使用MarshalAs(UnamangedType.ByValArray)的Marshal.Copy和固定大小的數組來構建基元的可變大小數組的示例。在需要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#中我有一個單獨工作的正弦波結構

[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

@HansPassant當然更簡單釘陣列? –

+0

它是。也許警告OP,他的C代碼不應該存儲指針是合適的。正弦波需要時間來回放;) –

+0

@Hans這些看起來像它們被處理成一個單一的值返回 –

回答

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(); 
}