Returning and passing void pointers to mex functions

15 次查看(过去 30 天)
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.

回答(4 个)

James Tursa
James Tursa 2013-5-13
编辑:James Tursa 2013-5-13
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 个评论
Francisco Paisana
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 2014-5-8
@Francisco: Could you open up a new Question and post the code you are having trouble with?

请先登录,再进行评论。


Oliver Woodford
Oliver Woodford 2015-12-27
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 2017-3-24
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 2017-3-24
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

类别

Help CenterFile Exchange 中查找有关 Write C Functions Callable from MATLAB (MEX Files) 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by