How can I pass a matrix to a function in a DLL defined with a double** header in MATLAB 7.10 (R2010a)?

1 visualizzazione (ultimi 30 giorni)
I'm trying to interface a C DLL with MATLAB using LOADLIBRARY.
My function has the following header:
double ProvaMatF(int r, int c, double **mat)
I'm using a double pointer to allow dynamic initialization (through MALLOC) of my array. The array in C is then defined by a double pointer pointing to an array of pointer that are referring to arrays of double values.
I'm not able to create a double pointer object in MATLAB that correctly represents my matrix. If I create a DoublePtrPtr with LIBPOINTER MATLAB Crashes while executing functions from the DLL.

Risposta accettata

MathWorks Support Team
MathWorks Support Team il 21 Mag 2010
When you create a MATLAB 2D array and you pass it to a C function with CALLLIB the corresponding data type is double[][n] and not double**. The data type of double[][n] is different from double** as double[][n] is a simple pointer. The fact that the indexing with mat[][] is the same in both cases is due to pointer syntax. The variables are stored in memory with a totally different approach.
CALLLIB is passing a MATRIX:
[out,b]=calllib('ProvaMat', 'ProvaMatF', int32(3), int32(3), A);
interpreting A has a single pointer with syntax double[][n].
To work around this issue:
1) You can modify your DLL with a single pointer header:
double ProvaMatF(int r, int c, double mat[][3])
In this case you will need to modify the header. The indexing in your code can be mat[][] as with a double pointer syntax. This example is discussed in the attached "Single Pointer" archive.The limitation of this solution is the fact that you need to specify the size of your matrix and then you can't make use of a totally dynamic matrix initialization.
2) You can modify your DLL changing the way you index into your matrix:
out += (*mat)[i*c+j];
You can keep your double pointer configuration but you should access with previous syntax to not index wrong memory areas leading to a crash of MATLAB. This is presented in the example in "Double Pointer" archive. This solution is not modifying your header but requires a modification in the way you are indexing in your algorithms.
3) You can create an additional wrapper DLL that you can use to import the matrix (with the previously presented methods) and then "reshape" in a double pointer form for dynamic allocation to be passed as input to your original function. This solution allows you to avoid modifying your original functions.
  1 Commento
A Jenkins
A Jenkins il 16 Lug 2015
The method #2 as described here did not work for me in MATLAB 2013b.
The following is my C function:
void Foo(int r, int c, double **mat)
{
int i,j;
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
//recommended on MATLAB answers
(*mat)[i*c+j]=i+(double)j/10;
}
}
}
For 3 rows and 4 columns, I would expect the row number i, in the integer, and the column number j, in the decimal part, like so:
0 0.1000 0.2000 0.3000
1.0000 1.1000 1.2000 1.3000
2.0000 2.1000 2.2000 2.3000
Instead, in MATLAB I get the following column major mapping:
>> pv = libpointer('doublePtrPtr',zeros(3,4));
>> calllib('Bar','Foo',3,4,pv)
>> pv.value
ans =
0 0.3000 1.2000 2.1000
0.1000 1.0000 1.3000 2.2000
0.2000 1.1000 2.0000 2.3000
So I must either reshape in MATLAB:
>> reshape(pv.value,4,3)'
ans =
0 0.1000 0.2000 0.3000
1.0000 1.1000 1.2000 1.3000
2.0000 2.1000 2.2000 2.3000
Or perform column major writes in C:
(*mat)[i+j*r]=i+(double)j/10;

Accedi per commentare.

Più risposte (0)

Tag

Non è stata ancora inserito alcun tag.

Prodotti


Release

R2010a

Community Treasure Hunt

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

Start Hunting!

Translated by