passing 2-dim array from c++ to managed c++ to c#

A

Andreas Reiff

Hi!

I want some communication to take place between a c++ app and a c++ .dll
with an intermediate managed/unmanaged c++ dll. Basicall, I want the
unmanaged c++ dll to have a callback to the unmanaged c++ app. Also, the
managed c++ part should call the c# dll. I don't mind about where the array
is created, but I need to be able to pass it around.

Anyhow, my problem is, that if I create an array in unmanaged c++ like

double **a;
a = new double*[10];
for (int i = 0; i < 10; i++)
a = new double[100];

I cannot pass it into c# (since I call this function via a delegate, which
right now requires a paramter like InArray (see below)?!).

So my code in managed c++ look like this

array<Object ^> ^ InArray = gcnew array<Object ^>(numberOfArrays);

for (int i = 0; i < numberOfArrays; i++)

InArray = gcnew array<double>(numberOfElements);



But this code again I cannot pass back into unmanaged c++.

When I try to pin_ptr each element of the array, I have the problem, that I
need a new pin_ptr for each element of the first dimension of the array, but
the array can actually be of any size, and anyhow, I would not want to have
10 lines of code just to pin_ptr all 10 1-dimensional arrays in the 2-dim
array.



Hope this is not too confusing?!

Best regards,

Andreas
 
V

Vladimir Nesterovsky

I want some communication to take place between a c++ app and a c++ .dll
with an intermediate managed/unmanaged c++ dll. Basicall, I want the
unmanaged c++ dll to have a callback to the unmanaged c++ app. Also, the
managed c++ part should call the c# dll. I don't mind about where the
array is created, but I need to be able to pass it around.

Anyhow, my problem is, that if I create an array in unmanaged c++ like

double **a;
a = new double*[10];
for (int i = 0; i < 10; i++)
a = new double[100];


In fact you're using array of pointers, with each element by chance refering
to array of doubles. This is called jagged array. In fact multidimensional
array can be thought as one dimensional. The good example is std::valarray.
I cannot pass it into c# (since I call this function via a delegate, which
right now requires a paramter like InArray (see below)?!).
...

You did not mention if you need to access elements of the array in managed
code.
 
B

Ben Voigt

Andreas Reiff said:
Hi!

I want some communication to take place between a c++ app and a c++ .dll
with an intermediate managed/unmanaged c++ dll. Basicall, I want the
unmanaged c++ dll to have a callback to the unmanaged c++ app. Also, the
managed c++ part should call the c# dll. I don't mind about where the
array is created, but I need to be able to pass it around.

Anyhow, my problem is, that if I create an array in unmanaged c++ like

double **a;
a = new double*[10];
for (int i = 0; i < 10; i++)
a = new double[100];

I cannot pass it into c# (since I call this function via a delegate, which
right now requires a paramter like InArray (see below)?!).

So my code in managed c++ look like this

array<Object ^> ^ InArray = gcnew array<Object ^>(numberOfArrays);

for (int i = 0; i < numberOfArrays; i++)

InArray = gcnew array<double>(numberOfElements);



But this code again I cannot pass back into unmanaged c++.

When I try to pin_ptr each element of the array, I have the problem, that
I need a new pin_ptr for each element of the first dimension of the array,
but the array can actually be of any size, and anyhow, I would not want to
have 10 lines of code just to pin_ptr all 10 1-dimensional arrays in the
2-dim array.


Perhaps you want

clr::array<double,2> InArray = gcnew
array<double>(numberOfRows,numberOfColumns); // note these two parameters
might possibly be reversed
pin_ptr<double> row0 = &InArray[0][0];
double* row1 = row0 + numberOfColumns;
double* row2 = row1 + numberOfColumns;
//etc
 
A

Andreas Reiff

Yes, I have to access the array in managed as well as unmanaged code.

But I can create it anywhere, as long, as I can access it everywhere else.
 
A

Andreas Reiff

Does the

pin_ptr<double> row0 = &InArray[0][0];

pinpoint the whole array?

Actually, it should be

array<double ,2> ^ InArray = gcnew array<double ,2>(numberOfArrays,
numberOfElements);

which I can then put into a new array of objects (which I actually need to
delegate)

array<Object ^> ^ InArray_ = gcnew array<Object ^>(1);

InArray_[0] = InArray;

now I can invoke the array in my c# code

mi3->Invoke(_Compiled, InArray_);

and also use it in the unmanaged code.

pin_ptr<double> pa = &(InArray[0,0]);

callcallback(numberOfArrays, &numberOfElements, (double*)pa);

Something like this. In unamanged c++ I have all the freedoms I relly need
:) again. Meaning I can do all the pointer arithmetics you already
suggested.

Thx a lot!




Ben Voigt said:
Andreas Reiff said:
Hi!

I want some communication to take place between a c++ app and a c++ .dll
with an intermediate managed/unmanaged c++ dll. Basicall, I want the
unmanaged c++ dll to have a callback to the unmanaged c++ app. Also, the
managed c++ part should call the c# dll. I don't mind about where the
array is created, but I need to be able to pass it around.

Anyhow, my problem is, that if I create an array in unmanaged c++ like

double **a;
a = new double*[10];
for (int i = 0; i < 10; i++)
a = new double[100];

I cannot pass it into c# (since I call this function via a delegate,
which right now requires a paramter like InArray (see below)?!).

So my code in managed c++ look like this

array<Object ^> ^ InArray = gcnew array<Object ^>(numberOfArrays);

for (int i = 0; i < numberOfArrays; i++)

InArray = gcnew array<double>(numberOfElements);



But this code again I cannot pass back into unmanaged c++.

When I try to pin_ptr each element of the array, I have the problem, that
I need a new pin_ptr for each element of the first dimension of the
array, but the array can actually be of any size, and anyhow, I would not
want to have 10 lines of code just to pin_ptr all 10 1-dimensional arrays
in the 2-dim array.


Perhaps you want

clr::array<double,2> InArray = gcnew
array<double>(numberOfRows,numberOfColumns); // note these two parameters
might possibly be reversed
pin_ptr<double> row0 = &InArray[0][0];
double* row1 = row0 + numberOfColumns;
double* row2 = row1 + numberOfColumns;
//etc
Hope this is not too confusing?!

Best regards,

Andreas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top