Visual C++ - 通过反向 PInvoke 将字节指针传递给 C# 方法

本文关键字:指针 字节 方法 PInvoke C++ Visual | 更新日期: 2023-09-27 17:56:29

过去,我将字节数组从 C# 方法传递到非托管C++函数。 我现在尝试使用反向 PInvoke 将指向无符号字符类型的缓冲区的指针从 C++ 方法传递回 C# 方法,该方法使用回调返回到 C# 代码。 我已经尝试了几种不同的想法 - 例如为第二个参数传递 Ref Byte、Byte * 和 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# 分配内存缓冲区,固定它们,并将它们传递给 C++ 方法。

Visual C++ - 通过反向 PInvoke 将字节指针传递给 C# 方法

所有 pinvoke 都很好,工作正常。 你只是在C++代码中有一个愚蠢的错误,你忘记了增加指针,所以你只设置数组的第一个元素。 用

   *p++ = Loop;

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

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