calling a c function with calllib doesn't work with pointers

조회 수: 11 (최근 30일)
Tommy Vasek
Tommy Vasek 2020년 6월 3일
편집: James Tursa 2020년 6월 5일
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
Tommy Vasek
Tommy Vasek 2020년 6월 4일
편집: Tommy Vasek 2020년 6월 4일
I will free the pointer outside the function, the moment I didn't need it anymore? Maybe I didn't see the point, but if I free it in the function addition, before the return, I can't return it after, and after the return, not possible.
I'm not really good at C, most of the time in this kind of situations I feel more confortable writing functions with the pointer which will stock the result as a parameter, and return a int to check if everything is ok. It doesn't seem possible to use such an option when code called from matlab, or at least I wanted to try something easier first.
Mohammad Sami
Mohammad Sami 2020년 6월 5일
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.

댓글을 달려면 로그인하십시오.

채택된 답변

Mohammad Sami
Mohammad Sami 2020년 6월 4일
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;
  댓글 수: 1
Tommy Vasek
Tommy Vasek 2020년 6월 4일
Thanks a lot, it works perfectly fine ! I wrote a new with question, this time with pointer of pointers, something quite close of what I want to use, if by chance you have any idea :-)

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

James Tursa
James Tursa 2020년 6월 5일
편집: James Tursa 2020년 6월 5일
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.

카테고리

Help CenterFile Exchange에서 Performance and Memory에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by