问题描述
我有一个无法导入vs2012 c#项目的dll.我以前使用过dllImport,但之前从未使用过元帅或指针.我想我很幸运.
I have a dll that I cannot import in my vs2012 c# project. I have used dllImport before but I have never had to use Marshal or pointers before. Lucky me I guess.
这是我当前拥有的代码.调用的函数是fnLDA_GetDevInfo(DEVID * ActiveDevices)DEVID是一个普通的无符号整数(#define DEVID无符号整数)
This is the code that I currently have.The function being called is fnLDA_GetDevInfo(DEVID *ActiveDevices)DEVID is a normal unsigned integer (#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);
我以这种方式在代码中调用函数
I call the function in my code this way
uint[] MyDevices;
fnLDA_GetDevInfo(ref MyDevices);
这时我得到一个错误:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
现在,我很确定会发生错误,因为我没有正确地指向指针.
Now I'm pretty sure the error occurs because I don't call the pointer right or something.
任何帮助将不胜感激.
推荐答案
您的间接访问级别更高.将数组整理为指向数组的指针.当您将参数声明为 ref
时,将再次传递一个指针.因此,您的C#代码与 uint **
相匹配.即使这样,您也不能将 ref
与数组类型一起使用,因为您不能期望非托管代码产生托管数组.
You have an extra level of indirection. An array is marshalled as a pointer to the array. When you declare the parameter as ref
, again a pointer is passed. Thus your C# code matches uint**
. Even so, you cannot use ref
with an array type because you cannot expect the unmanaged code to produce a managed array.
您的p/调用应该是:
[DllImport(DLLLOCATION,CallingConvention = CallingConvention.Cdecl)]
private static extern int fnLDA_GetDevInfo([Out] uint[] ActiveDevices);
请注意,此函数很难调用.由于未传递函数的长度,因此如果数组不够长,函数将无法避免耗尽数组的末尾.我真的希望您能找到一些方法来计算在调用此函数之前需要多大的数组.
Note that this function is pretty hard to call. Since the function is not passed the length of the array, it is impossible for the function to avoid running off the end of the array if the array is not long enough. I really hope that you have some way to work out how large the array needs to be ahead of calling this function.
所以也许您应该这样称呼它:
So perhaps you are expected to call it like this:
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 ++程序中进行其他工作.
I trust that you'll be able to work the rest out from the documentation for the DLL and/or the example C++ programs that call the DLL.
这篇关于带有指针的C#dllimport的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!