Returning and passing void pointers to mex functions

16 visualizaciones (últimos 30 días)
Paul Wessel
Paul Wessel el 12 de Mayo de 2013
Respondida: Paul Wessel el 24 de Mzo. de 2017
I have several C functions. A "create" function creates a large C structure and passes back a void * pointer to it. The other functions accepts this pointer as their first argument and internally knows how to cast to the original hidden structure. We are trying to build mex functions from this set of functions, with imagined use such as
P = createstuff; % return the void pointer
[A B] = dostuff(P, 13.5,15.6); % Call some mex function that returns two items
C = domorestuff (P, A, B); % Do something else
freestuff (P); % Free the memory pointed to by P inside the mex.
We are having trouble storing the void pointer P in Matlab. Is libpointer the way to go, declarit in a voidPtr? The P lets us pass large amounts of information, parameters, settings, between the individual mex functions.

Respuestas (4)

James Tursa
James Tursa el 13 de Mayo de 2013
Editada: James Tursa el 13 de Mayo de 2013
The simple answer is to encode it into a uint64 or int64 variable that can be passed around. E.g.,
To encode:
void *vp;
long long *ip;
union {long long theinteger; void *thepointer;} ivp;
:
ivp.theinteger = 0;
ivp.thepointer = vp; // your pointer
plhs[0] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL);
ip = (long long *) mxGetData(plhs[0]);
*ip = ivp.theinteger;
To decode:
void *vp;
long long *ip;
union {long long theinteger; void *thepointer;} ivp;
:
ip = (long long *) mxGetData(prhs[0]);
ivp.theinteger = *ip;
vp = ivp.thepointer; // your pointer
However, this raises several issues. If you ever lose track of the pointer at the MATLAB level you will have memory leak and resource tie-up issues. This could be caused for instance if you generate your P inside a function (a local variable) and then some totally unrelated function generates an error and pops you out of the function before you get a chance to call the freestuff(P). Also, it is unclear to me that the memory manager for your createstuff mex function has to necessarily be the same memory manager as your freestuff mex function. It would be if you used the MATLAB Memory Manager for all your allocations, but you don't state any details for what is behind P so I don't know. And then what happens if you inadvertantly clear the mex functions prior to calling freestuff(P)?
To avoid all those issues I would instead advise that you have only one mex function that you call with different options. E.g.,
P = stuff('create'); % return the void pointer
[A B] = stuff('do',P, 13.5,15.6); % Call some mex function that returns two items
C = stuff ('domore',P, A, B); % Do something else
stuff ('free',P);
That way everything is in one routine and you know there will be no memory manager issues. Also you should register a mexAtExit function inside stuff to make sure that P gets free'd if the mex function is cleared. If you can potentially have more than one 'P' floating around in memory at the same time, then you can more easily manage the array of such values inside one mex function as well.
If you really want to have seperate mex functions for all of this, then I would advise that you strongly consider at least having the allocate and deallocate functionality inside one mex routine.
  4 comentarios
Francisco Paisana
Francisco Paisana el 7 de Mayo de 2014
Could you provide the code you used for this? I am having troubles using the mexMakeMemoryPersistent and the mexAtExit.
Did you store the void* pointer in a global variable to release it at mexAtExit? How did you avoid the errors related to freeing a void * pointer that was not created through mxMalloc, mxRealloc, etc.
Tks for the attention
James Tursa
James Tursa el 8 de Mayo de 2014
@Francisco: Could you open up a new Question and post the code you are having trouble with?

Iniciar sesión para comentar.


Oliver Woodford
Oliver Woodford el 27 de Dic. de 2015
Whilst you are not interfacing to a C++ class, much of a similar discussion on how to reuse a pointer to a C++ class is relevant here.
The discussion in full is here , summarised here, with a minimal working example here .

Santosh Tiwari
Santosh Tiwari el 24 de Mzo. de 2017
It is important to mention that in Matlab the corresponding returned data type is int64.
If you are creating a bunch of objects and storing them in Matlab, then you must use int64 when allocating storage.
handleIDs = zeros(numHandles,1,'int64');
Now, handleIDs can correctly store the pointer addresses.

Paul Wessel
Paul Wessel el 24 de Mzo. de 2017
Thanks to all for feedback. In the end we went with
static uintptr_t *pPersistent; /* To store API address back and forth within a single MATLAB session */
and this is working very well for us. Cheers, Paul

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by