简体   繁体   English

带有指针的C#dllimport

[英]c# dllimport with pointers

I have a dll that I cannot import in my vs2012 c# project. 我有一个无法导入vs2012 c#项目的dll。 I have used dllImport before but I have never had to use Marshal or pointers before. 我以前使用过dllImport,但之前从未使用过元帅或指针。 Lucky me I guess. 我猜很幸运。

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) 调用的函数为fnLDA_GetDevInfo(DEVID * ActiveDevices)DEVID是普通的无符号整数(#define DEVID无符号整数)

//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);

At this point I get an error: 此时,我得到一个错误:

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. 现在,我很确定会发生错误,因为我没有正确调用指针。

Any help would be appreciated. 任何帮助,将不胜感激。

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. 当您将参数声明为ref ,再次传递了一个指针。 Thus your C# code matches uint** . 因此,您的C#代码与uint**相匹配。 Even so, you cannot use ref with an array type because you cannot expect the unmanaged code to produce a managed array. 即使这样,您也不能将ref与数组类型一起使用,因为您不能期望非托管代码产生托管数组。

Your p/invoke should be: 您的p / invoke应为:

[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);

Or perhaps like this: 也许像这样:

int len = fnLDA_GetDevInfo(null);
uint[] MyDevices = new uint[len];
fnLDA_GetDevInfo(MyDevices);

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. 我相信您将能够从DLL文档和/或调用DLL的示例C ++程序中进行其余工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM