【问题标题】:Pass multi - dimensional array from managed code to unmanaged code将多维数组从托管代码传递到非托管代码
【发布时间】:2011-11-01 11:36:05
【问题描述】:

我想做以下事情:

  1. 在 C# 代码中创建三个维度数组,如下所示:

    var myArray = new short[x,y,z];
    UnanagedFunction(myArray);
    
  2. 像这样将它传递给非托管代码 (c++):

    void UnmanagedFunction(short*** myArray)
    {
        short first = myArray[0][0][0];
    }
    

更新 当我尝试以下代码时,出现运行时错误:

试图读取或写入受保护的内存。

谢谢!!!

【问题讨论】:

  • 你不能用 C++ 编写这样的代码。
  • 代码的第一部分在 c# 中,第二部分在 c++ 中,我现在尝试了编译器允许我使用 c++ 代码
  • 也许您可以将代码更改为三元组数组。
  • @Simon,一组三元组有什么帮助?您是指四倍(x、y、z 和值)吗?
  • 你甚至不能在纯 C++ 中做到这一点。您必须在函数原型上编写除一维之外的所有维度。阅读:c-faq.com/~scs/cclass/int/sx9a.html(例如void UnmanagedFunction(short myArray[][10][10]))

标签: c# c++ marshalling dllimport


【解决方案1】:
IntPtr Array3DToIntPtr(short[, ,] Val)
        {
            IntPtr ret = Marshal.AllocHGlobal((Val.GetLength(0) + Val.GetLength(1) + Val.GetLength(2)) * sizeof(short));

            int offset = 0;
            for (int i = 0; i < Val.GetLength(0); i++)
            {

                for (int j = 0; j < Val.GetLength(1); j++)
                {
                    for (int k = 0; k < Val.GetLength(2); k++)
                    {
                        Marshal.WriteInt16(ret,offset, Val[i, j, k]);
                        offset += sizeof(short);


                    }
                }
            }

            return ret;
        }

这已经过测试并且有效,唯一的限制是你必须在完成后调用数组指针上的Marshal.FreeHGlobal,否则你会出现内存泄漏,我还建议你改变你的 c++函数,以便它接受数组尺寸,否则您将只能使用特定大小的 3d 数组

【讨论】:

    【解决方案2】:

    我是用纯 C# 编写的,但如果你从 Func 中去掉 unsafe static,Func 应该可以在 C/C++ 中工作。请注意,我确定可以写这个:-) 我正在使用这个Indexing into arrays of arbitrary rank in C#

    static unsafe void Main(string[] args) {
        var myArray = new short[5, 10, 20];
    
        short z = 0;
    
        for (int i = 0; i < myArray.GetLength(0); i++) {
            for (int j = 0; j < myArray.GetLength(1); j++) {
                for (int k = 0; k < myArray.GetLength(2); k++) {
                    myArray[i, j, k] = z;
                    z++;
                }
            }
        }
    
        // myArray[1, 2, 3] == 243
    
        fixed (short* ptr = myArray) {
            Func(ptr, myArray.GetLength(0), myArray.GetLength(1), myArray.GetLength(2));
        }
    }
    
    // To convert to C/C++ take away the static unsafe
    static unsafe void Func(short* myArray, int size1, int size2, int size3) {
        int x = 1, y = 2, z = 3;
        int el = myArray[x * size2 * size3 + y * size3 + z]; // el == 243
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 2016-06-01
      • 2013-08-24
      相关资源
      最近更新 更多