-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathmxGetPropertyPtr.cpp
executable file
·157 lines (145 loc) · 6.94 KB
/
mxGetPropertyPtr.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*************************************************************************************
*
* MATLAB (R) is a trademark of The Mathworks (R) Corporation
*
* Filename: mxGetPropertyPtr.c
* Programmer: James Tursa
* Version: 1.00
* Date: March 07, 2011
* Copyright: (c) 2011 by James Tursa, All Rights Reserved
*
* This code uses the BSD License:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*-------------------------------------------------------------------------
*
* This file is intended to be included in user source code to provide the
* capability to get the pointer to a property inside a C mex routine. The
* signature is as follows:
*
* #include "matrix.h"
* mxArray *mxGetPropertyPtr(const mxArray *pa, mwIndex index, const char *propname);
*
* If successful, the returned value will be a pointer to the named property
* of the object. Note that this differs from the behavior of the API routine
* mxGetProperty:
*
* mxGetPropertyPtr: Returns a pointer to the actual property itself.
* mxGetProperty: Returns a pointer to a *copy* of the property.
*
* If unsuccessful, the mxGetPropertyPtr will return NULL.
*
* Limitations of mxGetPropertyPtr:
* - Works on classdef objects, which require MATLAB R2008a or later.
* - Generally, the property that this pointer points to should be treated
* as read-only unless you REALLY, REALLY, KNOW WHAT YOU ARE DOING!
* - Works only in mex routines, not in Engine applications.
* - Requires a helper C-mex routine, GetPropertyPtrx.
* - Requires a helper m-file routine, GetPropertyPtr.
* - mxGetPropertyPtr uses unofficial behind-the-scenes hacking of the
* mxArray structure itself to recover the pointer. There is no guarantee
* that this will work on all versions of MATLAB. If it doesn't work for
* you, please contact the author with details of your problem.
*
* Although the intended use of mxGetPropertyPtr is for the newer classdef
* class variables (for which TMW did not supply an equivalent routine), in
* fact mxGetPropertyPtr will also work with structures and old-style user-
* define classes as well, treating propname as a fieldname.
*
* Using mxGetPropertyPtr is much more efficient for large size properties
* than using mxGetProperty because no large intermediate copy of the
* property is created. This will result in speed increases as well as
* avoiding potential out-of-memory conditions that can result from using
* mxGetProperty. Also, on some versions of MATLAB the mxGetProperty function
* can return an invalid pointer in out-of-memory cases and using this
* pointer will crash MATLAB. For small size properties, the extra overhead
* involved with mxGetPropertyPtr (calling mexCallMATLAB with calls the
* m-file GetPropertyPtr which calls another mex routine GetPropertyPtrx)
* outweighs its benefits and one would be better off calling the API
* function mxGetProperty instead. But if you don't know the size of the
* property in advance and the size could be large, it would be advisable
* to use mxGetPropertyPtr.
*
* Change Log:
* 2011/Mar/07 --> 1.00, Initial Release
*
****************************************************************************/
#ifndef mxGetPropertyPtr_c /* Include guard */
#define mxGetPeopertyPtr_c
/* Includes ----------------------------------------------------------- */
#include "mex.h"
/* Macros ------------------------------------------------------------- */
#ifndef INT64_TYPE
#define INT64_TYPE long long
#endif
#ifndef MWSIZE_MAX
#define MWSIZE_MAX
#define mwIndex int
#define mwSignedIndex int
#define mwSize int
#endif
/* -------------------------------------------------------------------- *
* mexCallMATLABWithTrap first introduced in R2008b. *
* For earlier versions use this intermediate interface instead. *
* The macro mxSetLogical is set in matrix.h in R2008a and earlier, but *
* not in R2008b and later. Use that to determine need for trap code. *
* -------------------------------------------------------------------- */
#ifdef mxSetLogical
mxArray *mexCallMATLABWithTrap(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], const char *functionName)
{
mexSetTrapFlag(1);
if( mexCallMATLAB(nlhs,plhs,nrhs,prhs,functionName) ) {
return mxCreateDoubleScalar(0.0); /* Return something (anything) that is non-NULL to indicate error */
} else {
return NULL;
}
}
#endif
/* -------------------------------------------------------------------- */
mxArray *mxGetPropertyPtr(const mxArray *pa, mwIndex ix, char *propname)
{
mxArray *mx, *PropertyPtr = NULL;
mxArray *lhs[1], *rhs[3];
union {INT64_TYPE theinteger; mxArray *thepointer;} uip; /* For non-compliant code use below */
if( pa && propname && ix >= 0 ) {
if( mxIsStruct(pa) ) { /* If a struct, just use mxGetField directly */
PropertyPtr = mxGetField(pa,ix,propname);
} else { /* Otherwise, assume a classdef object and go get the pointer */
rhs[0] = (mxArray *) pa;
rhs[1] = mxCreateDoubleScalar(ix+1);
rhs[2] = mxCreateString(propname);
mx = mexCallMATLABWithTrap(1,lhs,3,rhs,"GetPropertyPtr");
if( !mx && lhs[0] ) {
uip.theinteger = *((INT64_TYPE *)mxGetData(lhs[0]));
PropertyPtr = uip.thepointer; /* Need to use non-compliant union code to avoid compiler bug */
mxDestroyArray(lhs[0]);
}
if( mx ) mxDestroyArray(mx);
mxDestroyArray(rhs[2]);
mxDestroyArray(rhs[1]);
}
}
return PropertyPtr;
}
#endif /* mxGetPropertyPtr_c */