Returning and passing void pointers to mex functions

16 Ansichten (letzte 30 Tage)
Paul Wessel
Paul Wessel am 12 Mai 2013
Beantwortet: Paul Wessel am 24 Mär. 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.

Antworten (4)

James Tursa
James Tursa am 13 Mai 2013
Bearbeitet: James Tursa am 13 Mai 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 Kommentare
Francisco Paisana
Francisco Paisana am 7 Mai 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 am 8 Mai 2014
@Francisco: Could you open up a new Question and post the code you are having trouble with?

Melden Sie sich an, um zu kommentieren.


Oliver Woodford
Oliver Woodford am 27 Dez. 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 am 24 Mär. 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 am 24 Mär. 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

Kategorien

Mehr zu Write C Functions Callable from MATLAB (MEX Files) finden Sie in Help Center und File Exchange

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by