如何在 C# 中使用 p/invoke 传递指向数组的指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/289076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:48:14  来源:igfitidea点击:

How can I pass a pointer to an array using p/invoke in C#?

c#capipinvoke

提问by Randy Sugianto 'Yuku'

Example C API signature:

C API 签名示例:

void Func(unsigned char* bytes);

void Func(unsigned char* bytes);

In C, when I want to pass a pointer to an array, I can do:

在 C 中,当我想传递一个指向数组的指针时,我可以这样做:

unsigned char* bytes = new unsigned char[1000];
Func(bytes); // call

How do I translate the above API to P/Invoke such that I can pass a pointer to C# byte array?

如何将上述 API 转换为 P/Invoke,以便我可以传递指向 C# 字节数组的指针?

采纳答案by asponge

The easiest way to pass an array of bytes is to declare the parameter in your import statement as a byte array.

传递字节数组的最简单方法是将导入语句中的参数声明为字节数组。

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true]
public extern static void Func(byte[]);

byte[] ar = new byte[1000];
Func(ar);

You should also be able to declare the parameter as an IntPtr and Marshal the data manually.

您还应该能够将参数声明为 IntPtr 并手动封送数据。

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true]
public extern static void Func(IntPtr p);

byte[] ar = new byte[1000];
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(byte)) * ar.Length);
Marshal.Copy(ar, 0, p, ar.Length);
Func(p);
Marshal.FreeHGlobal(p);

回答by FlySwat

You can use unsafe code:

您可以使用不安全代码:

unsafe 
{
     fixed(byte* pByte = byteArray)
     IntPtr intPtr = new IntPtr((void *) pByte);
     Func(intPtr);
}

If you need to use safe code, you can use a few tricks:

如果你需要使用安全代码,你可以使用一些技巧:

IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(byteArray));
Marshal.Copy(byteArray, 0, intPtr, Marshal.SizeOf(byteArray));

Func(intPtr);

Marshal.FreeHGlobal(intPtr);

However, the safe code is going to be slow IMHO.

但是,恕我直言,安全代码会很慢。

回答by JaredPar

Here is the appropriate signature for the native function.

这是本机函数的适当签名。

[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")]
public static extern  void Func(System.IntPtr bytes) ;