我有一个需要在非托管C DLL中调用函数的C#应用程序。我有它使用各种功能,所以设置似乎都很好。我能够将ref short
传递给其中一个函数,它会更新变量中的值。但是,我遇到了一些使用long []
作为输入的不同函数的问题,并且应该更新它以保存关于图像的一堆值。这是函数在.h文件中的样子:
short GetImage (
short nIndex,
long arrImageParam []
);
以下是我们的C#代码在添加函数时的样子:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate short GetImage(short nIndex, int [] arrImageParam);
我正在调用这样的函数:
var arrImageParam = new int [20];
short b = GetImage.Invoke(1, arrImageParam);
这不起作用 - 当我尝试在Visual Studio中查看数组中的值时,我收到消息“无法读取内存”。我认为这是因为我们没有正确编组。
我们也试过这样的功能(使用“ref”):
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate short GetImage(short nIndex, ref int [] arrImageParam);
用ref输入调用它:
short c = GetImage.Invoke(1, ref arrImageParam);
给出错误:
FatalExecutionEngineError' - “附加信息:运行时遇到了致命错误。错误的地址是0x72cfe248,在线程0xf4c上。错误代码是0xc0000005。”
我们也在下面尝试了这个,但它似乎也没有正常工作 - 它将输出数组设置为2的长度并且似乎没有任何实际值
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate short GetImage(short nIndex, ref IntPtr arrImageParam);
-
int[] array2 = new int[20];
int size = array2.Length;
for (int i = 0; i < array2.Length; i++)
{
array2[i] = i;
}
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(size)
* array2.Length);
Marshal.Copy(array2, 0, buffer, array2.Length);
short c = GetImage.Invoke(1, ref buffer);
int[] arrayRes = new int[size];
Marshal.Copy(buffer, arrayRes, 0, size);
Marshal.FreeCoTaskMem(buffer);
Console.WriteLine("\nInteger array passed ByRef after call:");
foreach (int i in arrayRes)
{
Console.Write(" " + i);
}
那么,将数组传递给这个要求long []并返回填充数组的C DLL函数的正确方法是什么?
答案 0 :(得分:0)
我设法让它返回一些我可以变成数组并从中获取元素的东西。以下是它对我有用的方法:
IntPtr pointer = Marshal.AllocHGlobal(2048);
short b = GetImage.Invoke(imageUploadCounter, pointer);
int[] managedArray = new int[21];
Marshal.Copy(pointer, managedArray, 0, 21);
int imageID = managedArray[10];