如何在 C# 中使用数组返回类型的 DLLImport 函数?

Yup*_*ore 3 c# c++ pinvoke

这里是: static uint8_t* Compress(const uint8_t* input, uint32_t inputSize, uint32_t* outputSize, int compressionLevel);

我试过了 :

[DllImport("Mini7z.dll")]
public static extern byte[] Compress(byte[] input, uint inputSize, out uint outputSize, int compressionLevel);
Run Code Online (Sandbox Code Playgroud)

和这个

[DllImport("Mini7z.dll")]
public static extern byte[] Compress(byte[] input, uint inputSize, uint* outputSize, int compressionLevel);
Run Code Online (Sandbox Code Playgroud)

但似乎没有任何作用

PMF*_*PMF 5

您需要告诉编组器从函数返回时需要生成的数组的大小。因此,您需要在返回值上指定一个属性。

尝试这个:

        [DllImport("Mini7z.dll")]
        [return:MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 2)]
        public static extern byte[] Compress(byte[] input, uint inputSize, [In, Out] ref uint outputSize, int compressionLevel);
Run Code Online (Sandbox Code Playgroud)

请注意,这会泄漏缓冲区。您需要调用另一个方法来释放它。最终,您需要使用IntPtras 返回类型并手动进行编组才能正确返回内存。

由于托管类型byte[]无法转换回返回的原始指针,因此您应该执行以下操作:

        [DllImport("Mini7z.dll")]
        public static extern IntPtr Compress(byte[] input, uint inputSize, [In, Out] ref uint outputSize, int compressionLevel);
        [DllImport("Mini7z.dll")] 
        public static extern FreeMemory(IntPtr memory); // or however the method is named
        
        // Then, use like this:
        IntPtr data = Compress(input, inputSize, ref dataSize, 9);
        byte[] managedData = new byte[dataSize];
        Marshal.Copy(data, managedData, 0, dataSize);
        FreeMemory(data);
Run Code Online (Sandbox Code Playgroud)