C#如何从非托管C++中获取int*数组



在非托管端,我有short* m_pLevels[4],我需要获得指向C#端的指针数组,这样我就可以使用每个点从非托管端复制到托管数组
如何将short*的数组转换为C#?该数组会是IntPtr的数组吗?

我建议使用C++/CLI在C#(托管(和C++(本机(之间进行通信。在下面的例子中,我使用了最简单的情况,其中本地数据只是1个二进制缓冲区。您可以调整它以传递任何形式的本地数据。

您可以采取以下两种方法之一:

  1. 最有效的方法是将非托管数据传递给C#并按原样使用。
    您必须使用unsafe方法来处理原始指针。它效率高,但风险更大。一个不安全的C#方法获取本地缓冲区的例子:

    unsafe void HandleNativeData(sbyte* pData, int dataLen)
    {
    // ...
    }
    
  2. 最安全的方法是将非托管内存封送为托管内存
    例如,如果您有一个C#或C++/CLI方法,它从C++获得了一个原始指针(如方法1(,则可以执行以下操作:

    unsafe void HandleNativeData(sbyte* pData, int dataLen)
    {
    byte[] DataManagedBuf = new byte[dataLen];
    Marshal.Copy((IntPtr)pData, DataManagedBuf, 0, dataLen);
    // At this point DataManagedBuf is a proper managed buffer,
    //  containing the data that was passed from native C++.
    }
    

PInvoke也是一个选项:

// this function pre-supposes that everyone knows there are always
// exactly 4 buffers of data. that's pretty rare for IRL interop.
// normally you'd use a struct with fixed length arrays, but the 
// question explicitly states short*[].
[DllImport("UnmanagedCode.dll", EntryPoint = "NameOfUnmanagedCodeFunction"]
private static extern void GetUnmanagedBuffers(IntPtr[] shortPtrs, int[] lengths);
// this function will call the unmanaged function and then
// marshal over the pointers into managed arrays
public List<short[]> GetBuffers()
{
var managedArrays = new List<short[]>(4);
// the unmanaged DLL fills in the buffer addresses for us
var shortPtrs = new IntPtr[4];
// and the lengths of each buffer
var lengths = new int[4];

GetUnmanagedBuffers(shortPtrs, lengths);
// input validation/exception handling omitted for brevity    
for (int i = 0; i < 4; i++)
{
var length = bufferLengths[i];
// create the array and add it to the return values
managedArrays.Add(new short[length]);
// the overload of Marshal.Copy that works with int16[]
Marshal.Copy(bufferPtrs[i],    //source pointer
managedArrays[i], //destination array
0,                //starting index into dest
length)           //number of int16 to copy
}
// often you'd see another PInvoke here telling the unmanaged 
// code that you're done with the buffers so they can be freed.
return managedArrays;
}

最新更新