I have a C DLL that im calling from a C# application. I am able to successfully receive the struct from the DLL but im having trouble sending the same struct with data into the DLL. Here is what I have:
C# application struct:
public class MatrixClass
{
private double[,] cells;
[StructLayout(LayoutKind.Sequential)]
public struct Matrix
{
public IntPtr cells;
public int cellRows;
public int cellColumns;
}
}
C DLL struct:
typedef struct
{
double **cells;
int cellRows;
int cellColumns;
} Matrix;
Here is an example function from My C DLL that I need to recieve the struct from:
void GetMatrixCell(Matrix *MatrixIn, int nRow, int nColumn, double *value)
{
*value = 0.0;
int nColIndex = nColumn - 1;
int nRowIndex = nRow - 1;
*value = MatrixIn->cells[nRowIndex][nColIndex];
}
How im calling it:
[DllImport(matrixDLL, CallingConvention = CallingConvention.Cdecl)]
static extern int GetMatrixCell(Matrix mIn, int nRow, int
nColumn, ref double value);
public double GetCell(int Row, int Column)
{
double result = 0.0;
int stride = Rows * sizeof(double);
IntPtr p = Marshal.AllocHGlobal(Rows * stride);
Matrix mIn = MatrixtoDLL(this, Rows, Columns, p, stride); //this = MatrixClass
GetMatrixCell(mIn, Row, Column, ref result);
Marshal.FreeHGlobal(p);
return result;
}
MatrixtoDll Funtion from above:
public static Matrix MatrixtoDLL(MatrixClass input, int rows, int columns, IntPtr p, int stride)
{
Matrix toReturn = new Matrix ();
toReturn.cellColumns = columns;
toReturn.cellRows = rows;
for (int i = 0; i < columns; i++) //rows
{
double[] temp = new double[rows];
for (int x = 0; x < rows; x++)
temp[x] = input.cells[i, x]; //[columns, rows]
Marshal.Copy(temp, 0, p + stride * i, rows);
}
toReturn.cells = p;
return toReturn;
}
Im thinking my MatrixtoDLL is where I need to rethink? or I need to be sending the data another way. Like I mentioned above I can successfully receive the data (cells) as an IntPtr and convert it to a 2d array but the program does not like they way im trying to send the struct. Thanks in advance!
Edit: This is the unhandled exception I get: An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll Additional information: Exception has been thrown by the target of an invocation.
Your P/Invoke function is not defined correctly. It shoud be
Furthermore,
Matrix.cellsshould be a pointer to an array of pointers to one-dimensional arrays, in other words a jagged array.We can use
GCHandlefor this, this also avoids unnecessary copyingI must say, I'm unclear the point of
Matrix.cellColumnsandcellRows. The C function doesn't seem to use it.