2013-12-19 82 views
0

我有一個函數定義在本地C++文件如下:pinvoking本地C++功能,給予堆棧溢出錯誤

void fun(byte* arg1, int* arg2, byte arg3) {} 

所以,從我的C#文件,我打電話的功能如下:

fun(ref byte[] arg1, ref int arg2, byte arg3); 

不應該照顧這個?

+0

忘記使用DllImport.CallingConvention是一個標準錯誤。你的代碼片段很糟糕。 –

+0

我用它,我只是在這裏包括它。我只是專注於數據類型。對不起,如果我的代碼段不符合您的高標準。我仍然是一個學習者 –

回答

1

A byte[]被編組爲指向數組的第一個元素的指針。這正是你在非託管方面所需要的。您已使用ref byte[],它具有額外的虛假間接級別。所以,你的代碼可以簡單地是:

[DllImport(...)] 
fun(byte[] arg1, ref int arg2, byte arg3); 

編組由釘住它處理的字節數組,所以參數爲輸入/輸出。儘管我懷疑你實際上只會將數據從託管傳遞到非託管。但是,如果您的非託管代碼修改了該陣列,那麼這些修改實際上將直接針對固定的託管陣列進行。

2

我建議:

fun([MarshalAs(UnmanagedType.LPArray)] byte[] arg1, ref int arg2, byte arg3) 

See MarshalAsUnmanagedType

您對應於C++ byte **ref byte[] arg1

0

第一個參數是指向一個字節的對象,如果你的意思是說,它是一個數組,我會使用一個IntPtr

public static extern void fun(ref IntPtr arg1, ref int arg2, byte arg3); 

這將轉化爲

public static extern void fun(ref byte arg1, ref int arg2, byte arg3); 

我發現PInvoke Interop Assitant對這類東西非常有用。另請參閱pinvoke.net使用大量標準DLL導入。

+0

你如何打算將'byte []'作爲'IntPtr'傳遞? –

+0

你的答案肯定是很靈活,我不知道這個屬性。我會做類似於[這種方法](http://stackoverflow.com/questions/537573/how-to-get-intptr-from-byte-in-c-sharp),雖然我會釋放內存一個'finally'塊。 – Matt

+0

這並不是說它變得光滑。這更多的是你的答案是錯誤的。你可以使用'IntPtr'而不是'ref IntPtr',並手動封送數組。例如通過固定它。但這不是一個好主意。從根本上說,你的代碼提交的問題與代碼中的錯誤相同。你有太多的間接程度。 –