c# dllimport with pointers

寵の児 提交于 2021-02-17 01:59:15

问题


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.

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

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.


回答1:


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.

Your p/invoke should be:

[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.



来源:https://stackoverflow.com/questions/26992178/c-sharp-dllimport-with-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!