【问题标题】:Working with 2D managed and unmanaged 2D arrays使用 2D 托管和非托管 2D 阵列
【发布时间】:2014-09-06 09:02:47
【问题描述】:

我正在处理一个需要我在 C# 和非托管 C++ 之间传递二维数组的项目。

我需要为 2D 整数数组和 2D 浮点数组执行此操作,但现在我被困在 2D 整数数组上。

我有一个一维整数数组的模式工作得很好......

我的演示 C# 代码如下所示

// Test 2D integer Array
int[,] cs2DIntArray = new int[5,2];
cs2DIntArray[0, 0] = 0;
cs2DIntArray[0, 1] = 1;
cs2DIntArray[1, 0] = 10;
cs2DIntArray[1, 1] = 11;
cs2DIntArray[2, 0] = 20;
cs2DIntArray[2, 1] = 21;
cs2DIntArray[3, 0] = 30;
cs2DIntArray[3, 1] = 31;
cs2DIntArray[4, 0] = 40;
cs2DIntArray[4, 1] = 41;


int my2DArrayIntReturn = tess.test2DIntArray(cs2DIntArray, 5, 2); 

“tess”是一个托管的 C++ Wrapper 类,并像这样实现 test2DIntArray 方法,

int test2DIntArray(array<int, 2>^ my2DIntArray, int rows, int columns){

    using System::Runtime::InteropServices::GCHandle;
    using System::Runtime::InteropServices::GCHandleType;

    GCHandle my2DIntArrayGCHandle = GCHandle::Alloc(my2DIntArray,GCHandleType::Pinned);
    IntPtr my2DIntArrayPtr = my2DIntArrayGCHandle.AddrOfPinnedObject();

    my2DIntArray[0, 0] = 0;
    my2DIntArray[0, 1] = 11;
    my2DIntArray[1, 0] = 110;
    my2DIntArray[1, 1] = 111;
    my2DIntArray[2, 0] = 120;
    my2DIntArray[2, 1] = 121;
    my2DIntArray[3, 0] = 130;
    my2DIntArray[3, 1] = 131;
    my2DIntArray[4, 0] = 140;
    my2DIntArray[4, 1] = 141;

    return pu->uTest2DIntArray((int*)my2DIntArrayPtr.ToPointer(),rows,columns);

};

pu是非托管类,像这样实现uTest2DIntArray

int UnmanagedModel::uTest2DIntArray(int* my2DIntArray, int arrayRows, int arrayColumns)
{

            my2DIntArray[0,0] = 20;
            my2DIntArray[0,1] = 21;
            my2DIntArray[1,0] = 210;
            my2DIntArray[1,1] = 211;
            my2DIntArray[2,0] = 220;
            my2DIntArray[2,1] = 221;
            my2DIntArray[3,0] = 230;
            my2DIntArray[3,1] = 231;
            my2DIntArray[4,0] = 240;
            my2DIntArray[4,1] = 241;




        return my2DIntArray[1,1];


}

编译和运行时不会出现错误或警告,但是当代码返回 C# 时,只有前两个值 [0,0] 和 [0,1] 反映了对非托管代码中的值所做的更改,如下所示。所有其他值都反映了在托管 C++ 方法中所做的更改。

cs2DIntArray    {int[5, 2]} int[,]
        [0, 0]  240 int
        [0, 1]  241 int
        [1, 0]  110 int
        [1, 1]  111 int
        [2, 0]  120 int
        [2, 1]  121 int
        [3, 0]  130 int
        [3, 1]  131 int
        [4, 0]  140 int
        [4, 1]  141 int

谁能看到/解释我做错了什么以及需要做些什么来纠正此代码?我已经有一段时间没有编码了,我确实花了很长时间在 Google 上寻找解决方案,但无法完全按照需要完成这项工作。

我们将不胜感激。

道格

更多信息

  1. 如果我将非托管代码中的索引更改为使用单个索引(从 0 到 9)而不是二维索引(0,0 到 4,1),那么所有值都会正确更新
  2. 在调试器中,当我查看每个数组 value[x,y] 的地址时,它们都显示完全相同的地址
  3. 使用 2D 数组索引,似乎第一个索引被完全忽略了 - 仅使用了第二个索引,因为它从 0 到 1 不等,所以代码只是覆盖了前两个数组值。
  4. 这告诉我,我确实可以访问非托管代码中数组的正确内存,但我无法使用 2D 索引来访问它。这是一种痛苦,必须解决。

【问题讨论】:

    标签: c# c++ arrays unmanaged managed


    【解决方案1】:

    c++ 没有二维数组。逗号运算符将 4,0 变为 0,因此 my2DIntArray[4,0] 等价于 my2DIntArray[0]

    由于my2DIntArray 是指向一维数组的指针,您必须通过手动计算索引来模拟二维:my2DIntArray[line * columns + column]

    【讨论】:

    • Thanx @youdontneedtothankme ..... :) 你的解释完全符合我的发现。关于如何调整代码以便可以在非托管 C++ 代码中使用二维数组索引的任何想法?
    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2011-08-31
    相关资源
    最近更新 更多