0

I am working in a project that requires optimization and I want to translate one part of the code from C# to C++. I am using a C++\CLI wrapper but I am really new with this approach and I have not come to understand it completely. The following code returns an error when I run the program and I don't know the reason.

The C# program is the following:

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));

The C++/CLI project as follows:

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

The Unmanaged C++ code:

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;
}

It compiles well but when I run it I get the following error:

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

The casting to double pointer is a bad strategy but it is the only thing that came into my mind. Also, I know that C++ doesn't have 2D arrays just like C# has, but I need the multidimensional array in C# and I can not change it to write a jagged array Arr[][].

Thanks in advance.

4
  • That cast got you into trouble, the C++ code assumes it is a jagged array and it is not. Declare the argument int*, use arr[i * size + j] to index the array. Commented Mar 6, 2018 at 11:54
  • I will do that, do I need to previously fix the array using fixed{} in the C# code? I didn't do this in the code I showed up but the array may be moved to another location inside the memory while my C++ code is reading from it. Commented Mar 7, 2018 at 9:48
  • No, the pinvoke marshaller takes care of pinning the array. Commented Mar 7, 2018 at 9:49
  • Thank you so much! Commented Mar 8, 2018 at 10:14

1 Answer 1

1

You should copy managed array to unmanaged one and then do the computations:

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, I will try to do it too and see how is its performance!

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.