I have been working with an example from the MSDN that demonstrates marshalling a one-dimensional array.

http://msdn2.microsoft.com/en-us/library/9b1fy41s(VS.80).aspx

When I try to follow the example and pass a pointer to the two dimensional array, the unmanaged code only sees the first dimension. I think I can marshal these arrays if I use the right syntax, but because I am somewhat of a C++ noob, I am not quite getting it right. My dump of the pointer to the 2-d array, xmatrix, only shows numbers from the first dimension of the array.

The code is posted below. If you try this, simply create a C# class that creates a GSLMultiLinRegression object.

Can someone please help me with the syntax of passing a two dimensional array from managed C++ to unmanaged C++.

Thanks,

Ben

////////////Managed C#////////////////

GSLMultiLinRegression mlr = new GSLMultiLinRegression();

mlr.setXMatrix(indepArray,79,8); //I have a two dimensional array of

mlr.setYVector(predictedArray);

mlr.doMultiLinRegression();

Console.WriteLine("");

Console.WriteLine("Done Processing");

Console.ReadLine();

//////////////////////////////////////////////////

///////////Managed/Unmanaged C++//////////////////////////

#include "stdafx.h"

#include "gsl/gsl_multifit.h"

#include <time.h>

#using <System.dll>

// wrap_native_class_for_mgd_consumption.cpp

// compile with: /clr /LD

#include <windows.h>

#include <vcclr.h>

#include <stdio.h>

#using <System.dll>

using namespace System;

#pragma unmanaged

//a column of depenedent variable values

struct DepdendantVariableColumn{

double* col_values;

};

void computeMLRBestFit(double* xmatrix, double*yvector,double* coeffs,

double* cov, double* chisq,int matrix_length,int matrix_width){

gsl_matrix *X,*covmat;

gsl_vector *Y,*c;

X = gsl_matrix_alloc(matrix_length,matrix_width);

Y = gsl_vector_alloc(matrix_length);

c = gsl_vector_alloc(matrix_length);

covmat = gsl_matrix_alloc(matrix_length,matrix_width);

int i = 0;

int j = 0;

printf("Printing out dep array\n");

for (i =0; i < matrix_length;i++){

gsl_vector_set(Y,i,yvector);

printf("%d = %g\n",i,yvector);

}

for (i = 0; i < matrix_width;i++){

for (j= 0; j < matrix_length;j++){

gsl_matrix_set(X,i,j,xmatrix[i,j]);

printf("%d,%d = %g\n",i,j, xmatrix[i,j]);

}

}

}

#pragma managed

public ref class GSLMultiLinRegression{

//here's my logic. All I have to do is marshall arrays between the managed worlds

//and the unmanaged world. I will keep all the data local the managed class,

//shuffle the data over to the unmanaged class to do the computation,

//then keep the results back in the managed class.

public:

void doMultiLinRegression(){

pin_ptr<double> pp_xm = &XMatrix[0,0];

//pin_ptr<DepdendantVariableColumn> pp_dvc = &DepVarCols[0];

pin_ptr<double> pp_yv = &YVector[0];

Coeffs = gcnew array<double,1>(matrix_length); //just re-initialize the array

pin_ptr<double> pp_cf = &Coeffs[0];

Covs = gcnew array<double,2>(matrix_width,matrix_length);

pin_ptr<double> pp_cs = &chisq;

computeMLRBestFit(pp_xm,pp_yv,pp_cf,pp_cf,pp_cs,matrix_length,matrix_width);

//computeMLRBestFit(pp_dvc,pp_yv,pp_cf,pp_cf,chisq,matrix_length,matrix_width);

}

array<double,1>^ getCoeffs(){

return Coeffs;

}

void setXMatrix(array<double,2>^ xmatrix,int numObs, int numParams){

//XMatrix = xmatrix;

//initialize an array of dependentvarcolumns the size of numParams.

//loop over each column and value and load the dependentvar columns.

//store each "column" -- a double array -- in the double array property of the

//dependantvarcolumn. store the depvarcol objects in an array.

matrix_length = numObs;

matrix_width = numParams;

//XMatrix = gcnew array<double>(2);

XMatrix = xmatrix;

}

void setYVector(array<double,1>^ yvector){

YVector = yvector;

}

private:

array<double,2>^ XMatrix;

array<double,1>^ YVector;

array<double,1>^ Coeffs;

array<double,2>^ Covs;

int matrix_length; //note that vector lenght will be the same as matrix length;

int matrix_width;

double chisq;

};