Passing variable size 2d-Array to C external library

16 views (last 30 days)
I'm writing a C library similar to the shrlibsample example. Specifically, I'm having trouble with a function that has a 2d-array as an input argument.
Is it possible to write a function similar to the multDoubleArray function but with variable size in both dimensions? I've tried using double pointers (pointer to pointer) but the indexing is not working as expected, even after casting the matrix in matlab prior to calling the function (Aptr = libpointer('doublePtrPtr',A)). Any help will be appreciated.

Answers (1)

Manoj Mirge
Manoj Mirge on 23 Feb 2023
Hi Guillermo,
Computer memory stores data in terms of one-dimensional arrays. For example, when you declare a 3-by-3 matrix, the software stores this matrix as a one-dimensional array with nine elements. By default, MATLAB stores these elements with a column-major array layout. The elements of each column are contiguous in memory.
Consider the matrix A:
A =
1 2 3
4 5 6
7 8 9
The matrix A is represented in memory by default with this arrangement:
1 4 7 2 5 8 3 6 9
So, every Matrix in MATLAB can be considered as 1D column vector where elements are stored column wise. That is why you can access elements in Matrix using Linear Indexing.
You can read more about linear indexing in MATLAB here .
If you want to pass variable size matrix to C library functions, you can just pass it as single pointer because MATLAB internally handle 2D matrix as 1D array. As in MATLAB if you have above mentioned matrix A then internally MATLAB is handling that matrix as 1D array as shown above.
If you get double pointer Aptr from the below command:
Aptr= libpointer("doublePtr",A);
You can just pass that Aptr to C library function that accepts double* data type variable. And in C code you can consider the 2D Matrix A from MATLAB as 1D array in C with elements arranged column wise as explained above.
To create C function that accepts variable size matrix, number of cols and number of rows you can simply write C function in C library as shown below:
% C library function
EXPORTED_FUNCTION void myfun(double *x , int row, int col){
int i=0;
%below loop will iterate over matrix column wise.
for(int i=0;i<col;i++){
for(int j=0;j<row;j++){
*x++ *= 3;
}
}
}
%And in MATLAB you can simply give single pointer as argument to the above function in c library.
loadlibrary("Mylibrary");
A=[1 2 3; 4 5 6 ];
Aptr=libpointer("doublePtr",A);
[row,col]=size(A);
calllib("Mylibrary","myfun",Aptr,row,col);
disp(Aptr.Value);
The output of above code would be:
Aptr.Value=
3 9 15
6 12 18
Hope this helps.
  1 Comment
Walter Roberson
Walter Roberson on 23 Feb 2023
Be careful. C has two different ways of handling arrays.
One of the ways is consecutive memory as described above. C indexes first by column and then by row so where in MATLAB, A(2,1) is the element in memory directly after the first element, but in C the second element in memory is A(1,2).
The other way that C deals with arrays is to have the first level contain pointers to row vectors. The contents of any one row is consecutive in memory but two rows need not be consecutive.
If you see a C declaration such as
double C[5][7]
then that is an example of an-consecutive. C[2] is a pointer to a vector of 7 values and C[1][4] indexes the vector C, pulls out the second pointer (first is C[0]) and then indexes to the 5th element of what is pointed to.
This is different from
double C[5,7]
which deals with consecutive memory.
It is very common to see the two-level form; so common that a lot of C programmers do not even know the other form exists.

Sign in to comment.

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!