使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++

Posted

技术标签:

【中文标题】使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++【英文标题】:passing 2D array from C# to unmanaged C++ using C++/CLI wrapper 【发布时间】:2018-08-14 03:53:50 【问题描述】:

我在一个需要优化的项目中工作,我想将部分代码从 C# 转换为 C++。我正在使用 C++\CLI 包装器,但我对这种方法真的很陌生,而且我还没有完全理解它。以下代码在我运行程序时返回错误,不知道是什么原因。

C#程序如下:

int[,] Arr = new int[5, 5];

        for (int i = 0; i < 5; i++)
        
            for (int j = 0; j < 5; j++)
            
                Arr[i, j] = i + j;
            
        

test.MatrixComputation(Arr, Arr.GetLength(0));

C++/CLI项目如下:

void MatrixComputation(cli::array<int, 2> ^arr, int size)
    
        pin_ptr<int> p_arr = &arr[0, 0];
        pu -> ChangeArray((int**)p_arr, size);
    

非托管 C++ 代码:

void Unmanaged::MatrixComputation(int** arr, int size)

    for (int i = 0; i < size; i++)
    
        for (int j = 0; j < size; j++)
        
            arr[i][j] = i + j;     // line 27
        
    

    std::cout << arr[2][2] << std::endl;

它编译得很好,但是当我运行它时出现以下错误:

*Line 27: System.NullReferenceException: Object reference not set to an instance of an object*

转换为双指针是一个糟糕的策略,但这是我唯一想到的。另外,我知道 C++ 没有像 C# 那样的 2D 数组,但我需要 C# 中的多维数组,我无法更改它来编写锯齿数组 Arr[][]。

提前致谢。

【问题讨论】:

那个演员给你带来了麻烦,C++ 代码假定它是一个锯齿状数组,但事实并非如此。声明参数 int*,使用 arr[i * size + j] 索引数组。 我会这样做,我是否需要事先在 C# 代码中使用 fixed 修复数组?我在显示的代码中没有这样做,但是当我的 C++ 代码正在从中读取时,数组可能会移动到内存中的另一个位置。 不,pinvoke marshaller 负责固定数组。 非常感谢! 【参考方案1】:

您应该将托管数组复制到非托管数组,然后进行计算:

void MatrixComputation(cli::array<int, 2> ^arr, int size)

    std::unique_ptr<int[]> myArray(new int[size * size]);
    for (auto y = 0; y < size; y++)
    
        for (auto x = 0; x < size; x++)
        
            myArray[y * size + x] = arr[x, y];
        
    

    pu -> ChangeArray(std::move(myArray), size);


void Unmanaged::MatrixComputation(std::unique_ptr<int[]> arr, int size)

    for (int i = 0; i < size; i++)
    
        for (int j = 0; j < size; j++)
        
            arr[i * size + j] = i + j;
        
    

    std::cout << arr[2 * size + 2] << std::endl;

【讨论】:

谢谢解答,我也试试看效果如何!

以上是关于使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++的主要内容,如果未能解决你的问题,请参考以下文章

C# 使用 CLI 包装器调用非托管 C++

P/Invoke 编组和解组 C# 和非托管 DLL 之间的二维数组、结构和指针

带有 Directx 11 的 WPF

将数组从非托管 C++ 传递到 C#

C++/CLI 包装器尝试使用 MFC CObject 继承

如何将 C# 中的二维数组传递给 C++ DLL?