Click here to Skip to main content
15,888,802 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
C++
  // C++

namespace whatever
{

    public ref class Class1
    {

        public:
            static void Test(double **a, int nRow, int nCol)
            {
                           // Do something with 2D array.

            }

    };

}
//========================================================


C#
// C#

      using whatever

       private void button1_Click(object sender, EventArgs e)
        {

            double[,] a = new double[4, 3];
            a[0, 0] = 1; a[1, 0] = 1; a[2, 0] = 1; a[3, 0] = 0;
            a[0, 1] = 2; a[1, 1] = 1; a[2, 1] = 1; a[3, 1] = 1;
            a[0, 2] = 1; a[1, 2] = 2; a[2, 2] = 1; a[3, 2] = 15;


            unsafe
            {
                fixed (double** ppa = a) // What is the correct syntax?
                {

                    Class1.Test(ppa, a.GetLength(0), a.GetLength(1));
                }
            }

    }
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++





The C# syntax fixed (double** ppa = a) generated the following error message in VS2010 C#.

Error 1 Cannot implicitly convert type double* to double**. An explicit conversion exists (are you missing a cast?)

What is the correct way to pass the 2D array generated in the C# part over to the C++ ref class?
Posted
Updated 23-Oct-10 9:17am
v2

Unfortunately a managed multi-dimensional array is not equivalent to a pointer to pointer in native code. You could convert your 2-dimensional array into a doubly jagged array (an array of arrays) and then convert that to a pointer to a pointer and then pass that to C++.

But a more important question here is why you need to do this at all. Your C++ class is managed and can easily and trivially handle a managed array (including a 2-d array). So what do you need to resort to pointers for?
 
Share this answer
 
>> Would you show me how


This is an article I wrote some years back:

http://www.codeproject.com/KB/mcpp/cppcliarrays.aspx[^]

Scroll down to the section titled "Direct manipulation of CLI arrays using native pointers", and then the 2nd sub-section "Natively accessing a jagged array". You may need to change things just a little to fit your specific needs but that example should tell you what you need to do.
 
Share this answer
 
v4
The whole point is to avoid doing the unsafe code in C#. Pass the managed type (2-d or jagged array) to the C++/CLI ref class. The C++/CLI ref class converts this to the native pointer type and calls the native function. That's how this is typically done.

[Update (this comment vs answer thing is kinda messy!)]
----------------------------------------------------------------

Here's a sample showing how you can pass a 2-d array to a native function expecting a pointer to pointer.

C++
void Foo(double** nums, int xLen, int yLen)
{
    for (int i=0; i<xLen; i++)
    {
        for (int j=0; j<yLen; j++)
        {
            double d = *(double*)(nums[i] + j);
        }
    }
}

int main(. . .)
{
    array<double, 2>^ numbers = gcnew array<double, 2>(2,3);
    numbers[0,0] = 12.3;
    numbers[0,1] = 2.1;
    numbers[0,2] = 4.3;
    numbers[1,0] = 23.2;
    numbers[1,1] = 7.7;
    numbers[1,2] = 17.6;

    pin_ptr<double> p1 = &numbers[0,0];
    pin_ptr<double> p2 = &numbers[1,0];
    double* p3[2];
    p3[0] = p1;
    p3[1] = p2;
    double** p4 = p3;

    Foo(p4, 2, 3);

    return 0;
}
 
Share this answer
 
v2
Comments
firmwaredsp 24-Oct-10 20:05pm    
Nishant, thanks for posting your code.


Your solution works if you know at compile time the dimensions of your array. I came up with a solution that will allow a user to enter the array dimensions at run time. I want to post my code. Unfortunately, this blasted editor has a mind of its own and adds symbols. If you tell me how you posted your code without the unwanted symbols, I will then post mine so as to help someone in need in the future.

i.e void Nishant_PinnedArray (array&lt;double, 2&gt;^ numbers, const int nRow, int nCol)
Nish Nishant 24-Oct-10 20:08pm    
Reposting my comment from the deleted answer:

Well my example was just to show you how to do it. There is no need to know the dimensions at compile time.

And as for pasting code, for me I have the reverse problem, it treats every paste I do as code and I have to go remove the pre-tags it auto-adds.
On the C# side :

double[,] ar = new double[nRow, nCol];

// Load values into ar.

// From C# pass to C++/CLI ref class.
Class1.Test(ar);

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

On C++ side:

void Class1::Test(array<double,>^ ar)
{
/*
How do I pass the 'ar' array to Native(double** a)?

Your article showed how to use a pinned ptr for a 1D and jagged arrays, but not for a 2D array.

Is there a way to use a pinned pointer on a 2D array?
*/


}

void Class1::Native(double** a) { // do something }
 
Share this answer
 
v3
Comments
Nish Nishant 24-Oct-10 7:53am    
No, you cannot comprehensively access a 2-d array via a pinned pointer. It's got to be a jagged array.
Nish Nishant 24-Oct-10 7:56am    
With some hacking around, you may technically be able to have a double** pointing to the 2-d array. What you do is point the double* members in the double** to each dimension (by doing the math).
Nish Nishant 24-Oct-10 8:13am    
I've updated one of my answers above with some sample code.
Toli Cuturicu 24-Oct-10 14:49pm    
Convert your fake answers to appropriate comments by tomorrow or I will delete them!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900