MATLAB Answers

0

Returning and passing void pointers to mex functions

Asked by Paul Wessel on 12 May 2013
Latest activity Answered by Paul Wessel on 24 Mar 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.

  0 Comments

Sign in to comment.

4 Answers

Answer by James Tursa
on 13 May 2013
Edited by James Tursa
on 13 May 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 Comments

Show 1 older comment
1) Keep track of all the "good" P values inside the mex function. I.e., maintain a list of such values and always check the input against that list before using it.
2) I don't know anything about Octave so can't offer any advice there.
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
@Francisco: Could you open up a new Question and post the code you are having trouble with?

Sign in to comment.


Answer by Oliver Woodford on 27 Dec 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 .

  0 Comments

Sign in to comment.


Answer by Santosh Tiwari on 24 Mar 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.

  0 Comments

Sign in to comment.


Answer by Paul Wessel on 24 Mar 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

  0 Comments

Sign in to comment.