calling a c function with calllib doesn't work with pointers
16 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Tommy Vasek
le 3 Juin 2020
Modifié(e) : James Tursa
le 5 Juin 2020
I want to call a external C library I developped from matlab (ubuntu 18.04, matlab R2020a). I make a first test where everything was ok, with a simple addition function, but when I try things a little harder with pointers, that doesn't work anymore.
The easy test going right
1) First I create files addition.h and addition.c
addition.h
#include <stdio.h>
#include <stdlib.h>
double addition( double a, double b) ;
addition.c
#include <stdio.h>
#include <stdlib.h>
#include "addition.h"
double addition( double a, double b)
{
return a + b ;
}
2) Create a .so library with gcc
gcc -c addition.c -o addition.o
gcc -o addition.so -shared addition.o
3) call it from matlab
loadlibrary("addition","addition.h")
sortie = calllib("addition","addition", 2, 3)
And sortie is set to 5, everything is OK.
Now I try to put some spices by summing two arrays, and everything went wrong. Here is the C file.
#include <stdio.h>
#include <stdlib.h>
#include "addition.h"
double* addition( double* a, double* b, int n) // n is the length of a and b
{
double* sortie = malloc( n * sizeof(double) ) ;
for (int i = 0 ; i<n ; i++ )
{
sortie[i] = a[i] + b[i] ;
}
return sortie ;
}
I try to call it from matlab using calllib by two ways, no one worked.
First try
loadlibrary("addition","addition.h")
[s1,s2,s3] = calllib("addition","addition", [4,5,6], [1,2,3], int32(3))
Second try
a = libpointer("doublePtr",[4,5,6])
b = libpointer("doublePtr",[1,2,3])
[s1,s2,s3] = calllib("addition","addition", [4,5,6], [1,2,3], int32(3))
Event the signature of the function I got from libfunctions is quite weird, I don't see why I should have three outputs.
Could it have something to see with the version of gcc? I notice, reading posts about another approch (mex file) that we can have a version problem with gcc
3 commentaires
Mohammad Sami
le 5 Juin 2020
I am not sure if you can free the pointers created in C in Matlab. You would have to write another function to free the memory in C. The delete the pointer in Matlab.
Réponse acceptée
Mohammad Sami
le 4 Juin 2020
It will not return you 3 different values, it will return you pointer to an array containing 3 double values.
Also you need to pass in your two double arrays as pointers.
a = libpointer('doublePtr',[4 5 6]);
b = libpointer('doublePtr',[1 2 3]);
n = int32(3);
s = calllib("addition","addition", a, b, n);
s.setdatatype('doublePtr',double(n),1);
out = s.Value;
Plus de réponses (1)
James Tursa
le 5 Juin 2020
Modifié(e) : James Tursa
le 5 Juin 2020
A basic general outline of freeing the memory would be:
double *sortie = NULL; // top level variable
void free_sortie(void)
{
if( sortie ) {
free(sortie);
sortie = NULL;
}
double* addition( double* a, double* b, int n) // n is the length of a and b
{
if( sortie ) free_sortie();
sortie = malloc( n * sizeof(double) ) ;
for (int i = 0 ; i<n ; i++ )
{
sortie[i] = a[i] + b[i] ;
}
return sortie ;
}
You call addition( ) to do the addition, then you immediately follow that up with a call to free_sortie( ) to free the memory.
However, even this isn't really foolproof, since there is no mechanism to automatically free the memory if the dll is unloaded from memory. It relies on the user doing it manually. Also, there is no check if malloc( ) fails and returns a NULL.
0 commentaires
Voir également
Catégories
En savoir plus sur Performance and Memory dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!