2011-10-05 102 views
1

我要瘋了。DLLImport get嘗試讀取或寫入受保護的內存

我有一個DLL,使用此功能:

function MyFunc(myId: integer; var LstCB: array of char): integer; stdcall; 

第一個參數是一個貧窮的整數。 但第二個是一個char [2048]這得到成才這樣

('9', #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '2', '5', '0', '7', #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '2', '6', '0', #13, #10, '8', '8', '8', '8', '0', '0', '0', '0', '0', '0', '0', '0', '3', '3', '1', '5', #13, #10, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0,....#0) 

我今年進口用的DllImport:

[DllImport(@"MyDll.dll", EntryPoint = "MyFunc", CallingConvention = CallingConvention.StdCall)] 
internal static extern int MyFunc(int myId, string list); 

我也得到:

Attempted to read or write protected memory. This is often an indication that other memory has been corrupted. 

你有一些想法請?

謝謝。

回答

4

你的Delphi函數使用一個開放數組作爲字符串參數。這不應該通過DLL邊界暴露。調用Delphi開放數組的協議是特定於實現的。

您應該更改您的Delphi代碼以獲得PChar

function MyFunc(myId: Integer; LstCB: PChar): Integer; stdcall; 

如果數據從C#傳遞給Delphi DLL,那麼你的P/invoke沒問題。如果DLL旨在將數據返回給C#代碼,那麼您需要在P/invoke中聲明文本參數爲StringBuilder

[DllImport(@"MyDll.dll", EntryPoint = "MyFunc", CallingConvention = CallingConvention.StdCall)] 
internal static extern int MyFunc(int myId, StringBuilder list); 
... 
StringBuilder list = new StringBuilder(2048); 
int res = MyFunc(ID, list); 
string theList = list.ToString(); 

唯一的其他東西需要注意的是什麼樣的char意思是在Delphi中。如果DLL是使用Delphi 2009或更高版本構建的,那麼char是一個Unicode字符,您需要在您的P/invoke中指定CharSet

+0

爲了闡明,這個失敗的原因是它不平衡堆棧。 「字符數組」(array.Length字節)的大小與C#字符串指針(4/8字節)不一樣,所以參數會污染堆棧並導致未定義的行爲。 – Polynomial

+0

謝謝你,這麼多,我會試試這個。 – Tkanos

相關問題