You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中IntPtr转byte数组:已知C++行列信息时的实现及崩溃问题

Fixing the IntPtr to Byte Array Conversion & Unity Crash Issue

Alright, let’s tackle this interop problem between C++ and Unity— I’ve run into similar memory boundary crashes before, so I know exactly where to look. First, let’s confirm the core assumption here: since you mentioned size = rows * cols * 3 works in another project, your C++ uchar* is almost certainly pointing to RGB image data (3 bytes per pixel). That’s the foundation of our solution.

Step 1: Correctly Calculate the Byte Array Size

The math rows * cols * 3 is right for RGB, but we need to make sure the values of rows and cols are valid in C#:

  • Ensure the C++ code returns these as signed integers (not unsigned types like uint), because converting an unsigned value larger than int.MaxValue to C# int will result in a negative number— which would make totalBytes negative, causing a catastrophic memory access crash.
  • Add sanity checks for non-positive values (e.g., rows <= 0 or cols <= 0) before proceeding; invalid dimensions are a common crash trigger.

Step 2: Safe Marshal.Copy Implementation

Here’s how to structure the C# code to avoid boundary errors:

using System.Runtime.InteropServices;
using UnityEngine;

public class ImageInterop : MonoBehaviour
{
    // Import your C++ functions
    [DllImport("YourCppLibraryName.dll")]
    private static extern IntPtr GetImageData(out int rows, out int cols);

    [DllImport("YourCppLibraryName.dll")]
    private static extern void FreeImageData(IntPtr data);

    public byte[] ConvertCppImageToByteArray()
    {
        // Get the image pointer and dimensions from C++
        IntPtr imagePtr = GetImageData(out int rows, out int cols);

        // Guard against invalid pointers or dimensions
        if (imagePtr == IntPtr.Zero)
        {
            Debug.LogError("C++ returned a null image pointer!");
            return null;
        }
        if (rows <= 0 || cols <= 0)
        {
            Debug.LogError($"Invalid image dimensions: {rows}x{cols}");
            FreeImageData(imagePtr);
            return null;
        }

        // Calculate total bytes and create the array
        int totalBytes = rows * cols * 3;
        byte[] imageBytes = new byte[totalBytes];

        try
        {
            // Copy data from unmanaged memory to managed byte array
            Marshal.Copy(imagePtr, imageBytes, 0, totalBytes);
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Failed to copy image data: {ex.Message}");
            FreeImageData(imagePtr);
            return null;
        }

        // Critical: Free the unmanaged memory allocated by C++
        FreeImageData(imagePtr);

        return imageBytes;
    }
}

Why Your Unity Project is Crashing (And How to Fix It)

The crash is almost certainly a memory boundary violation— here are the most likely culprits:

  1. Invalid Memory Pointer: If your C++ code returns a pointer to stack-allocated memory (instead of heap-allocated with new[]), the memory gets freed immediately after the C++ function returns. Accessing this in C# causes a crash. Ensure your C++ code uses heap allocation, and provides a dedicated function to free the memory (like FreeImageData in the example above).
  2. Mismatched Data Format: If your C++ image is actually RGBA (4 bytes per pixel) instead of RGB, rows*cols*3 will be too small— Marshal.Copy will read past the end of the allocated memory. Double-check the image format in your C++ code.
  3. Row Stride Alignment: Some image libraries add padding bytes to each row to align memory (e.g., to 4-byte boundaries). In this case, rows*cols*3 won’t equal the actual memory size. You’ll need to modify your C++ function to return the row stride (bytes per row) instead of just rows/cols, then calculate totalBytes = rows * stride.
  4. Type Mismatches: If C++ uses size_t for rows/cols, converting that to C# int can cause overflow on large images. Use long for the size calculation if you’re dealing with high-resolution images.

Critical Memory Management Note

Never use Marshal.FreeHGlobal to free memory allocated by C++ with new[]— this will cause memory corruption. Always use a C++-exported function to free the memory, as shown in the example.

内容的提问来源于stack exchange,提问作者Dilara Albayrak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:23:14