我有一个 dll 无法导入到我的 vs2012 c# 项目中。我以前使用过 dllImport,但以前从未使用过 Marshal 或指针。我想我很幸运。
这是我目前拥有的代码。
被调用的函数是 fnLDA_GetDevInfo(DEVID *ActiveDevices)
DEVID 是一个普通的无符号整数(#define DEVID unsigned integer)
//Allocate an array big enough to hold the device ids for the number of devices present.
//Call fnLDA_GetDevInfo(DEVID *ActiveDevices), which will fill in the array with the device ids for each connected attenuator
//The function returns an integer, which is the number of devices present on the machine.
[DllImport(DLLLOCATION,CallingConvention = CallingConvention.Cdecl)]
private static extern int fnLDA_GetDevInfo([MarshalAs(UnmanagedType.LPArray)] ref uint[] ActiveDevices);
我在代码中这样调用该函数
uint[] MyDevices;
fnLDA_GetDevInfo(ref MyDevices);
此时我得到一个错误:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
现在我很确定会发生错误,因为我没有正确调用指针或其他东西。
任何帮助,将不胜感激。
你有一个额外的间接级别。数组被编组为指向数组的指针。当您将参数声明为ref
,再次传递一个指针。因此你的 C# 代码匹配uint**
。即使如此,你也不能使用ref
使用数组类型,因为您不能期望非托管代码生成托管数组。
你的 p/invoke 应该是:
[DllImport(DLLLOCATION,CallingConvention = CallingConvention.Cdecl)]
private static extern int fnLDA_GetDevInfo([Out] uint[] ActiveDevices);
请注意,这个函数很难调用。由于函数没有传递数组的长度,因此如果数组不够长,函数就不可能避免超出数组末尾。我真的希望您有某种方法可以在调用此函数之前计算出数组需要有多大。
所以也许你应该这样称呼它:
uint[] MyDevices = new uint[SomeLargeNumberThatYouPresumablyCanProvide];
int len = fnLDA_GetDevInfo(MyDevices);
或者也许像这样:
int len = fnLDA_GetDevInfo(null);
uint[] MyDevices = new uint[len];
fnLDA_GetDevInfo(MyDevices);
我相信您将能够从 DLL 的文档和/或调用 DLL 的示例 C++ 程序中解决其余问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)