From: Frédérick Cyr on
Greetings to all,

My question is "How can I assign a C pointer to a MATLAB object's property? (And not to a copy of the property)." Here are the details:

I'm currently working on a project where I create MATLAB objects to store my data and use mex-files to create matrix from the objects and do the calculations I need. To do so, I create a C structure filled with various pointers within the mex-file to easily access the MATLAB objects' properties. The thing is, I would like to reuse this structure of pointer to my objects' properties between two call to my mex function so I would not need to recreate it every time the objects' properties are changed.

I tried to simply declare a static pointer and assign it to the value returned by mxGetProperty, but to no avail since this function seems to return a pointer on a copy of the property rather than a pointer on the property itself. I searched the web and mathworks hopping to find a hint on how to do so or a new way to use my data. So here I am, asking the community for advices :).

The only workaround I have for now is recreating the structure of pointers every time I call the mex function, but I doubt it is the most time efficient solution. I have also been pointed to java objects and I've been thinking about using a C++ object or a C structure that I could keep up to date every time I modify my MATLAB object via my "set" operations... Even though my favorite solution would be static pointers to the properties, any comments or new ideas on the workarounds are welcome!

My code is too large to be displayed here, so I reproduced a simple example that recreate and illustrate perfectly my situation:

%% in folder @myClass:

% myClass.m:
classdef myClass
properties
structure;
end
methods
function obj = myClass()
end
end
end

% myMexFile.c (compiled to myMexFile.mexw32, of course):
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* Pointer that I want to point to my matlab object at all time. */
static double *ptr;

/* Initialise the pointer if any arguments other than "obj" are given. */
if (nrhs != 1){
ptr = mxGetPr(mxGetField(mxGetProperty(prhs[0], 0, "structure"), 0, "field"));
}
/* Dereference the pointer. */
mexPrintf("Field is %1.10f\n", *ptr);
}


%% The function calls:
% testScript.m:

% Create object.
object = myClass();

% Initialize field.
object.structure.field = 2.718281828;

% Assign the pointer to the field.
object.myMexFile(1);

% Change field value.
object.structure.field = 1.4142;

% Dereferencing pointers.
object.myMexFile(); %Here, I'd like to obtain 1.4142

% Some operations that could likely cause the pointer to go bad.
A = rand(3);
clear A;

% Dereferencing pointers.
object.myMexFile(); %Here, I'd also like to obtain 1.4142


The result I want to obtain from this test is:
Field is 2.7182818280
Field is 1.4142000000
Field is 1.4142000000

What I get is:
Field is 2.7182818280
Field is 154693054697988630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000
Field is 154693054697988630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000

or
Field is 2.7182818280
Field is 0.0000000000
Field is 0.0000000000

In my project, I also obtain segmentation faults due to dereferencing pointers that point on deallocated temporary memory. I repeat the question: "How can I obtain a C pointer to the real MATLAB object's attribute? (by the real, I mean the one that is in my workspace and not a copy)".

Thank you very much for your time and help!

Fred
From: James Tursa on
"Frédérick Cyr" <phraide(a)videotron.ca> wrote in message <i2ca50$nlt$1(a)fred.mathworks.com>...
>
> My question is "How can I assign a C pointer to a MATLAB object's property? (And not to a copy of the property)."

I am unaware of any way to do this, since MATLAB does not give you any functions that return pointers to the original properties.

(snip)

> I tried to simply declare a static pointer and assign it to the value returned by mxGetProperty, but to no avail since this function seems to return a pointer on a copy of the property rather than a pointer on the property itself. I searched the web and mathworks hopping to find a hint on how to do so or a new way to use my data. So here I am, asking the community for advices :).
>
> The only workaround I have for now is recreating the structure of pointers every time I call the mex function, but I doubt it is the most time efficient solution. I have also been pointed to java objects and I've been thinking about using a C++ object or a C structure that I could keep up to date every time I modify my MATLAB object via my "set" operations... Even though my favorite solution would be static pointers to the properties, any comments or new ideas on the workarounds are welcome!

I think you may be stuck. The old style of user-defined classes (using the @directory approach with many overloaded files) was actually just a normal MATLAB structure with a different class tag. It was easy and efficient to get at the fields directly with pointers in a mex routine without extra copying. But for the new method of user-defined classes, that isn't the case. Then only official access that MATLAB gives you is the mxGetProperty function which as you have discovered creates a copy.

(snip)

> /* Initialise the pointer if any arguments other than "obj" are given. */
> if (nrhs != 1){
> ptr = mxGetPr(mxGetField(mxGetProperty(prhs[0], 0, "structure"), 0, "field"));

This is bad programming practice. Since mxGetProperty gets a *copy* of the property by dynamically allocating memory, you should capture that returned mxArray * value in a variable and then use that variable for a subsequent mxGetField call. That way, once you are done with it you can call mxDestroyArray on the *copy* of the property you just created and free the memory. The way you have it programmed above you are creating a memory leak. Basic C/C++ programming practice is that when a function returns a pointer that points to dynamically allocated memory, you need to capture it in a variable so you can free it later on. Do *not* simply use the result directly (e.g., in another function argument) and then forget the returned pointer (like you do above) as this will result in a memory leak since you will have lost your only access to the dynamically allocated memory.

That's all for now. I will look some more at your code later ...

James Tursa
From: Frédérick Cyr on
Thanks for the reply. I'll post a new message as soon as I find a way around this problem.

Fred