8

I would like to do the following:

  1. Create three dimesinal array in c# code like this:

    var myArray = new short[x,y,z];
    UnanagedFunction(myArray);
    
  2. Pass it to unmanaged code (c++) like this:

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

UPDATED When I try the following code I have runtime error:

Attempted to read or write to protected memory.

Thank you!!!

7
  • You can't write code like that in C++. Commented Aug 22, 2011 at 21:09
  • the first part of code is in c# the second is in c++ and i tried it now compiler allows me the c++ code Commented Aug 22, 2011 at 21:12
  • 1
    Maybe you can change your code to an array of triples. Commented Aug 24, 2011 at 12:00
  • 1
    @Simon, how is an array of triples going to help? Do you mean quadruples (x, y, z and the value)? Commented Aug 25, 2011 at 6:06
  • 1
    You can't even do that in pure C++. You must write all-but-one dimensions on the function prototype. Read this: c-faq.com/~scs/cclass/int/sx9a.html (so for example void UnmanagedFunction(short myArray[][10][10]) ) Commented Aug 25, 2011 at 7:20

2 Answers 2

8
+50
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;
        }

This has been tested and it works, the only limitation is that you have to call Marshal.FreeHGlobal on the array pointer when you are done with it or you will get a memory leak, I would also suggest that you change your c++ function so that it accepts the array dimensions or you will only be able to use 3d arrays of specific size

Sign up to request clarification or add additional context in comments.

Comments

2

I'm writing it in pure C#, but if you take away the unsafe static from Func, the Func should work in C/C++. Be aware that I'm note sure sure it's ok ok to write this :-) I'm using this 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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.