2012-03-27 38 views
1

我有這樣的功能:由C編寫的C#陣列的PInvoke

extern "C" __declspec(dllexport) void Step(int * oSamplesCount, float * oSamples){ 
    // (approximative syntax for clarity) 
    *oSamplesCount = new_samples_count (some number between 0 and 16000) 
    oSamples[ 0 .. new_samples_count ] = some floats (sound data) 
} 

我想從C#調用它:

float [] mSamples = new float[16000]; 

[DllImport("Lib.dll")] 
static extern void Step(ref Int32 oSamplesCount, [MarshalAs(UnmanagedType.LPArray,SizeConst=16000)] ref float [] oSamples); 

void update(){ 
    Int32 lSamplesCount = 0; 
    Step(ref lSamplesCount, ref mSamples); 
} 

C函數正確調用,填充樣本數組的for()循環沒問題,但它在返回和下一個C#行之間崩潰了,所以我想這與解組有關,雖然我不想要任何編組/解組(數組是blittable,必須寫入C)

我不能使用/不安全。我嘗試了SizeConst和其他各種排列。

任何幫助表示讚賞!

回答

1

您的密碼錯誤。數組參數不應該通過ref傳遞,因爲float[]已經是參考。像這樣做:

[DllImport("Lib.dll")] 
static extern void Step(ref Int32 oSamplesCount, float[] oSamples); 

注意,這會從託管到本機編組,然後再返回,所有的16000個值,每次調用Step。如果那太貴了,我認爲你需要進行手動編組。

+0

你是對的,float []已經是一個參考。那是我的錯誤。但是,如果我使用UnmanagedType.LPArray,它是否仍然編碼/取消組織16000個浮點數? – Calvin1602 2012-03-27 15:51:50

+0

是的。 'float []'的默認編組是'UnmanagedType.LPArray',所以你不需要指定。你的界面很奇怪。本地代碼每次追加。我可能會用AllocHGlobal這樣做,然後在完成調用'Step'後,將所有的浮點數複製到'float []'末尾。 – 2012-03-27 15:54:15