If I use non-dynamic arrays, all works
pmxArray = mxArray^;
perA_ptr: pmxArray;
perA: array[1..3,1..4] of double;
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 4*3*sizeof(double));
......
_mlflinprog1(1,perX_ptr,perF_ptr,perA_ptr,perB_ptr,perLB_ptr);
it's WORKS.
but i need to use dynamic arrays. And i have a problem
perA: array of array of Double;
SetLength(perA,4,3);
perA_ptr := mxCreateDoubleMatrix(4,3,mxREAL);
Move(perA, mxGetPr(perA_ptr)^, 12*sizeof(double));
doesnt work, only trash in array;
Move(perA[0,0], mxGetPr(perA_ptr)^, 4*sizeof(double));
- WORKS for first row, but i need to copy all array's data, IDK how to do that in delphi.
That's arrays I need for matlab c shared library.
Your static array is stored in one contiguous block. A two dimensional dynamic array is ragged. In C terms you have double**
. Although a Delphi array has extra book keeping, that's how you need to think of it.
So when you do
SetLength(perA, 4, 3);
you have an array perA
of length 4, each of whose elements is another array. Each inner array is of length 3. The 3 elements of each inner array are stored contiguously, but these arrays are not contiguous. Therefore you'll need to copy the rows one at a time.
Exactly how you implement this depends on whether your Delphi matrix is stored row-major or col-major. If the former then it's simplest to populate a matrix and then transpose it. The code for both variants might look like this:
type
TDoubleMatrix = array of array of Double;
function CreateDoubleMatrixColMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nCol, nRow);
end;
function CreatemxArrayFromColMajor(const M: TDoubleMatrix): PmxArray;
var
col: Integer;
nRow, nCol: Integer;
values: PDouble;
begin
nCol := Length(M);
Assert(nCol > 0);
nRow := Length(M[0]);
Assert(nRow > 0);
result := mxCreateDoubleMatrix(nRow, nCol, mxREAL);
values := mxGetData(result);
for col := 0 to nCol - 1 do
begin
Assert(Length(M[col]) = nRow);
Move(M[col], values^, nRow * SizeOf(Double));
inc(values, nRow);
end;
end;
function CreateDoubleMatrixRowMajor(nRow, nCol: Integer): TDoubleMatrix;
begin
SetLength(Result, nRow, nCol);
end;
function CreatemxArrayFromRowMajor(const M: TDoubleMatrix): PmxArray;
var
row: Integer;
nRow, nCol: Integer;
tmp: PmxArray;
values: PDouble;
begin
nRow := Length(M);
Assert(nRow > 0);
nCol := Length(M[0]);
Assert(nCol > 0);
tmp := mxCreateDoubleMatrix(nCol, nRow, mxREAL);
values := mxGetData(tmp);
for row := 0 to nRow - 1 do
begin
Assert(Length(M[row]) = nCol);
Move(M[row], values^, nCol * SizeOf(Double));
inc(values, nCol);
end;
mexCallMATLAB(1, @result, 1, @tmp, 'transpose');
mxDestroyArray(tmp);
end;
I've not even compiled any of this code. All my Matlab programming is done in C. But I think that the above should have the ideas that you need.