简体   繁体   English

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

[英]C# how to get an array of int* from unmanaged C++

On the unmanaged side I have short* m_pLevels[4] , I need to get this array of pointers to the C# side so I can then use each point to copy from the unmanaged side to a managed array.在非托管端,我有short* m_pLevels[4] ,我需要获取指向 C# 端的指针数组,以便我可以使用每个点从非托管端复制到托管数组。
How do I get an array of short* to C# and would that array be an array of IntPtr ?如何获得一个short*到 C# 的数组,该数组是IntPtr的数组吗?

I recomend using C++/CLI to communicate between C# (managed) and C++ (native).我建议使用C++/CLI在 C#(托管)和 C++(本机)之间进行通信。 In the examples below I used the simplest case where the native data is simply 1 binary buffer.在下面的示例中,我使用了最简单的情况,即本机数据只是 1 个二进制缓冲区。 You can adapt it to pass any form of native data.您可以对其进行调整以传递任何形式的本机数据。

You can take one of these 2 approches:您可以采用以下两种方法之一:

  1. The most efficient is to pass the unmanaged data to C# and use it as is.最有效的是将非托管数据传递给 C# 并按原样使用。 You will have to use an unsafe methods to handle raw pointers.您将不得不使用unsafe的方法来处理原始指针。 It's efficient but more risky.这很有效,但风险更大。 An example for an unsafe C# method getting a native buffer:获取本机缓冲区的不安全 C# 方法的示例:

    unsafe void HandleNativeData(sbyte* pData, int dataLen) { ... }

  2. The safest way is to marshal the unmanaged memory to managed one.最安全的方法是将非托管内存编组为托管内存。 If for example you have a C# or C++/CLI method that got a raw pointer from C++ (like in approach 1), you can do the following:例如,如果您有一个从 C++ 获得原始指针的 C# 或 C++/CLI 方法(如方法 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 is also an option: 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM