我在写一个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放在一起。 –