通过反向的PInvoke传递一个字节指针,C#方法(Passing a byte pointer t

2019-10-17 15:14发布

在过去,我已通过从C#方法的字节数组非托管C ++函数。 现在我想的指针unsigned char类型的从C ++方法的缓冲区传递回使用逆PInvoke的,它使用一个回调以返回到C#代码是C#方法。 我已经尝试了几种不同的思路 - 像传递参考字节,字节*和IntPtr的为第二个参数,但他们都不工作。 这是我使用的IntPtr测试代码:

C#代码:

namespace TestPInvoke
{
   class Program
   {
      static void Main(string[] args)
      {
         foo f = new foo();
         f.DispMsg();
      }
   }

   unsafe public class foo
   {
      public delegate void callback(int NumBytes, IntPtr pBuf);

      public static void callee(int NumBytes, IntPtr pBuf)
      {
         System.Console.WriteLine("NumBytes = " + NumBytes.ToString() + ", pBuf = ");
         String s = "";
         Byte* p = (Byte*)pBuf.ToPointer();
         for (int Loop = 0; Loop < 50; Loop++)
         {
            s += p++->ToString() + "  ";
         }
         System.Console.WriteLine(s);
      }

      public void DispMsg()
      {
         caller(new callback(foo.callee));
      }

      [DllImport(@"C:\Users\Bob\Documents\Visual Studio 2008\Projects\AttackPoker1\Win32Client\TestPInvoke\bin\Debug\TestPInvokeDLLCPP.dll", CallingConvention = CallingConvention.StdCall)]
      public static extern void caller(callback call);
   }

}

C ++代码:

#include <stdio.h>
#include <string.h>

typedef unsigned char Byte;

typedef void (__stdcall *callback)(const int bytesInMsg, Byte* pintBuf);

extern "C" __declspec(dllexport) void __stdcall caller(callback call)
{
   // Debug Test on how to pass a pointer to a byte buffer to a C# method.
   Byte* pBuf = new Byte[50];
   // Initialize the buffer to something.
   Byte* p = pBuf;
   for (Byte Loop = 0; Loop < 50; Loop++)
      *p = Loop;
   // Initiate the callback into the C# code.
   call(50, pBuf);
   // Delete pBuf later.
}

当C ++代码调用C#回调被叫方的方法,所述bytesInMsg论点是正确的。 但是,返回的指针不指向缓冲区的开始。 取消引用指针似乎总是指向缓冲器(49或0X31),但在内存窗口看着它后,之前和之后的字节其余的都是垃圾的最后一个值。

有没有人对我怎么能得到这个没有编组的大型阵列工作有什么建议? 什么我希望做的是一个指针传递给在C ++侧一次创建一个C#类,那么,将能够有效地从该缓冲区读取数据的大缓冲区。

如果无法做到,那么我将不得不从C#分配内存缓冲区,PIN它们,并将它们传递到C ++方法。

Answer 1:

所有的PInvoke是罚款和工作正常。 你只需要在你的C ++代码傻的错误,你忘了,所以你永远只能设置数组的第一个元素递增指针。 采用

   *p++ = Loop;

或者更理智的版本,只是索引数组:

   // Initialize the buffer to something.
   for (int ix = 0; ix < 50; ++ix)
       pBuf[ix] = ix;


文章来源: Passing a byte pointer to a C# method via reverse PInvoke