2013-07-23 62 views
1

這裏是我的C函數:如何將字節從C返回到C#/。net?

DLL_PUBLIC void alve_ripemd320__finish(void* instance, uint32_t* out_hash) 
{ 
     ... 
    for (uint32_t i=0, i_end=10; i<i_end; i++) 
    { 
     out_hash[i] = h[i]; 
    } 
} 

,這裏是如何,我從C#調用它:

[DllImport(PlatformConstants.DllName)] 
static extern void alve_ripemd320__finish (IntPtr instance_space, ref byte[] hash); 

... 

public byte[] Finish() 
{ 
    byte[] result = new byte[40]; 
    alve_ripemd320__finish (c_instance, ref result); 
    return result; 
} 

,如果我評論的C代碼產生一個醜陋的內存設計缺陷,其消失上面寫到out_hash ....我的問題是,這是使用PInvoke傳遞字節緩衝區的正確方法?

+0

要問明顯的問題:當你從C調用'alve_ripemd320__finish'時是否工作? –

+0

@AustinSalonen我從來沒有從C中調用它,但是當我評論修改out_hash的代碼時,它可以工作(沒有做任何事情)。我知道這個錯誤可能在其他地方,但我的是/否問題:這是使用PInvoke傳遞字節緩衝區的正確方法嗎? – dsign

+0

當C API是無符號整數時,爲什麼要將C#端定義爲'byte []'? –

回答

2

您的C API正在寫入無符號整數。通常我希望它可以爲被映射:

[DllImport(PlatformConstants.DllName, CallingConvention=CallingConvention.Cdecl)] 
static extern void alve_ripemd320__finish(IntPtr instance_space, uint[] hash); 

public uint[] Finish() 
{ 
    uint[] result = new uint[10]; 
    alve_ripemd320__finish (c_instance, ref result); 
    return result; 
} 

這裏有三個主要變化:

  1. 我切換調用約定來Cdecl。這是C++編譯器的標準(除非你明確地切換到stdcallDLL_PUBLIC)。
  2. 我更改爲匹配您的C API,它使用32位無符號整數而不是字節。但是,如果您選擇,您應該能夠切換回byte[]
  3. 您不應該需要通過ref。這通常與接受uint32_t** out_hash的C API相當,而不是uint32_t* out_hash,它應直接映射到數組。
+0

謝謝你,第三點真的很有幫助。 – dsign