简体   繁体   English

我怎样才能将数组从C#传递到一个非托管DLL中,并以long []形式获取值?

[英]How can I pass an array from C# to an unmanaged DLL as a long [] and get values back?

I have a C# application that needs to call functions in an unmanaged C DLL. 我有一个C#应用程序,需要在非托管C DLL中调用函数。 I have it working with various functions, so that setup seems to be all good. 我可以使用它的各种功能,因此设置似乎很好。 I am able to pass a ref short to one of the functions and it updates the value in the variable as it should. 我能够将ref short传递给其中一个函数,它会按需更新变量中的值。 However, I am running into some issues with a different function that takes a long [] as input and is supposed to update it to hold a bunch of values about an image. 但是,我遇到了另一个问题,该函数具有不同的功能,该功能需要很long []作为输入,并且应该对其进行更新以保存一堆有关图像的值。 Here is what the function looks like in the .h file: 该函数在.h文件中的外观如下:

short GetImage (
 short nIndex,            
 long  arrImageParam []
 );

And here is what our C# code looks like when it adds the function: 这是我们的C#代码添加功能时的样子:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate short GetImage(short nIndex, int [] arrImageParam);

I'm calling the function like so: 我这样调用函数:

var arrImageParam = new int [20];
short b = GetImage.Invoke(1, arrImageParam);

This does not work - I get the message "unable to read memory" when I try to look at the values in the array in Visual Studio. 这不起作用-当我尝试在Visual Studio中查看数组中的值时,收到消息“无法读取内存”。 I assume it is because we are not marshalling correctly. 我认为这是因为我们没有正确编组。

We also tried making the function like this (using "ref"): 我们还尝试过使函数如下(使用“ ref”):

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate short GetImage(short nIndex, ref int [] arrImageParam);

And calling it with a ref input: 并使用ref输入调用它:

short c = GetImage.Invoke(1, ref arrImageParam);

which gives an error: 这给出了一个错误:

FatalExecutionEngineError' - "Additional information: The runtime has encountered a fatal error. The address of the error was at 0x72cfe248, on thread 0xf4c. The error code is 0xc0000005." “ FatalExecutionEngineError'-”其他信息:运行时遇到致命错误。错误的地址为线程0xf4c上的0x72cfe248。错误代码为0xc0000005。

We also tried this below, but it didn't seem to work correctly either - it sets the output array to length of 2 and doesn't seem to get any real values 我们也在下面尝试了此方法,但是它似乎也无法正常工作-它将输出数组的长度设置为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);
       }

So, what is the correct way to pass an array into this C DLL function that asks for long[] and get back a filled array? 那么,将数组传递到要求long []并返回已填充数组的C DLL函数中的正确方法是什么?

I managed to get it to return something that I can turn into an array and get the elements from it. 我设法使它返回一些可以变成数组并从中获取元素的东西。 Here is how it worked for me: 这对我来说是这样的:

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

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

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