我在寫一個C#程序,調用sam-ba.dll
中的AT91Boot_Scan
函數。在該DLL的documentation中,此函數的簽名是void AT91Boot_Scan(char *pDevList)
。此功能的目的是掃描並返回連接設備的列表。C#「一堆已損壞」使用sam-ba.dll
問題:我現在的問題是,我每次調用此函數從C#的時間,在DLL的代碼引發a heap has been corrupted
例外。
除了:從我從閱讀documentation明白了,char *pDevList
參數是指向該函數可以使用存儲設備名稱緩衝區組成的數組。但是,調用從C#方法時,智能感知報告說,此功能的簽名實際上void AT91Boot_Scan(ref byte pDevList)
我有點困惑是這是爲什麼。一個字節不足以作爲指針。我們需要4個字節的32位和8個字節的64位...如果是ref
關鍵字是使這個參數爲指針,那麼我應該傳遞什麼字節?我的緩衝區數組中的第一個字節或第一個緩衝區的第一個字節?
代碼:我已經寫C#的方法調用該函數如下。
/// <summary>
/// Returns a string array containing the names of connected devices
/// </summary>
/// <returns></returns>
private string[] LoadDeviceList()
{
const int MAX_NUM_DEVICES = 10;
const int BYTES_PER_DEVICE_NAME = 100;
SAMBADLL samba = new SAMBADLL();
string[] deviceNames = new string[MAX_NUM_DEVICES];
try
{
unsafe
{
// Allocate an array (of size MAX_NUM_DEVICES) of pointers
byte** deviceList = stackalloc byte*[MAX_NUM_DEVICES];
for (int n = 0; n < MAX_NUM_DEVICES; n++)
{
// Allocate a buffer of size 100 for the device name
byte* deviceNameBuffer = stackalloc byte[BYTES_PER_DEVICE_NAME];
// Assign the buffer to a pointer in the deviceList
deviceList[n] = deviceNameBuffer;
}
// Create a pointer to the deviceList
byte* pointerToStartOfList = *deviceList;
// Call the function. A heap has been corrupted error is thrown here.
samba.AT91Boot_Scan(ref* pointerToStartOfList);
// Read back out the names by converting the bytes to strings
for (int n = 0; n < MAX_NUM_DEVICES; n++)
{
byte[] nameAsBytes = new byte[BYTES_PER_DEVICE_NAME];
Marshal.Copy((IntPtr)deviceList[n], nameAsBytes, 0, BYTES_PER_DEVICE_NAME);
string nameAsString = System.Text.Encoding.UTF8.GetString(nameAsBytes);
deviceNames[n] = nameAsString;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return deviceNames;
}
我一個解決方案,嘗試:我注意到,線byte* pointerToStartOfList = *deviceList;
未正確分配指針deviceList
到pointerToStartOfList
。地址總是被0x64關閉。
我想如果我在一個0x64則偏移硬編碼的兩個地址會匹配所有將被罰款。 pointerToStartOfList += 0x64;
但是,儘管強制地址匹配,我仍然得到了a heap has been corrupted
錯誤。
我的想法:我認爲在我的代碼中我要麼沒有正確創建緩衝區數組,要麼我沒有正確傳遞指針數組。
是MAX_NUM_DEVICES絕對夠大?根據我從文檔中可以看出的結果,迄今爲止所做的工作看起來都不錯......只有一件事,或許它不應該是'ref *',而應該只是傳遞指針。 –
是的,絕對。 sam-ba.dll的文檔沒有明確說明,但是他們提供了一個代碼示例,其中的設備數量是5(搜索'CHAR * strConnectedDevices [5];')我試圖複製他們的代碼示例,但它似乎寫成'C++'而不是'C#' – Calseon
這個庫設計得不是很好,真的只適合從C++程序調用。實際的參數類型是「字符串」,而不是「參考字節」。從技術上講,你可以通過ildasm.exe反編譯互操作庫來修復它,修改.il文件修復參數類型並將其與ilasm.exe放在一起。 –