【问题标题】:How can I pass a pointer to an array using p/invoke in C#?如何在 C# 中使用 p/invoke 将指针传递给数组?
【发布时间】:2013-03-04 16:12:03
【问题描述】:

示例 C API 签名:

void Func(unsigned char* bytes);

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

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

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

【问题讨论】:

    标签: c# c api pinvoke


    【解决方案1】:

    你可以使用不安全的代码:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

        您还应该能够将参数声明为 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);
        

        【讨论】:

        • 为什么第一种方法有效,而第二种方法无效。这就是我在 Windows Phone 应用程序上所面临的。
        • 我知道这篇文章有点旧,但Marshal.SizeOf(object) 不适用于数组。我敢肯定,如果您将数组传递给它,您会遇到异常,但我现在没有在我面前打开 VS 来尝试。要正确确定数组的大小,对于您的示例,代码将是 Marshal.SizeOf(typeof(byte)) * ar.Length
        • 是的,你是对的 9ee1。 Marshal.SizeOf 可用于结构但不能用于数组。我已经相应地更新了示例代码。谢谢。
        猜你喜欢
        • 2013-10-19
        • 2010-09-22
        • 1970-01-01
        • 2020-11-14
        • 2010-11-06
        • 1970-01-01
        • 1970-01-01
        • 2013-04-29
        相关资源
        最近更新 更多