Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
bbe8b12d
Commit
bbe8b12d
authored
8 years ago
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added matlab_object to the mex wrapper. Now you can have parameters that are
arbitrary matlab objects.
parent
4219185d
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
237 additions
and
76 deletions
+237
-76
call_matlab.h
dlib/matlab/call_matlab.h
+77
-2
example_mex_function.cpp
dlib/matlab/example_mex_function.cpp
+4
-0
mex_wrapper.cpp
dlib/matlab/mex_wrapper.cpp
+156
-74
No files found.
dlib/matlab/call_matlab.h
View file @
bbe8b12d
...
...
@@ -5,12 +5,29 @@
#define MIT_LL_CALL_MATLAB_H__
#include <string>
#include <sstream>
#include <dlib/error.h>
#include <dlib/assert.h>
namespace
dlib
{
// ----------------------------------------------------------------------------------------
struct
invalid_args_exception
:
error
{
/*!
WHAT THIS OBJECT REPRESENTS
This is the exception thrown when the mex wrapper tries to convert a matlab
object into a C++ object but for whatever reason can't (usually because the
types don't match).
!*/
invalid_args_exception
(
const
std
::
string
&
msg_
)
:
error
(
msg_
)
{}
invalid_args_exception
(
const
std
::
ostringstream
&
msg_
)
:
error
(
msg_
.
str
())
{}
};
// ----------------------------------------------------------------------------------------
void
check_for_matlab_ctrl_c
();
/*!
ensures
...
...
@@ -20,6 +37,62 @@ void check_for_matlab_ctrl_c();
// ----------------------------------------------------------------------------------------
class
matlab_object
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a simple wrapper around matlab's generic mxArray, which is the
thing that is matlab's "anything object". So a matlab_object can be used as an
argument to a mex_function() that can bind to any matlab object at all. It can
also bind to "nothing" and so is inherently also an optional argument when
present in a mex_funciton().
!*/
public
:
matlab_object
()
:
handle
(
0
),
should_free
(
false
),
arg_idx
(
0
)
{}
matlab_object
(
const
matlab_object
&
)
=
delete
;
~
matlab_object
();
// Check if a matlab object is bound to this object.
bool
is_empty
()
const
{
return
handle
==
0
;
}
operator
bool
()
const
{
return
handle
!=
0
;
}
// Convert from MATLAB to C++, throw invalid_args_exception if not possible.
template
<
typename
T
>
operator
T
()
const
;
template
<
typename
T
>
void
get
(
T
&
item
)
const
;
// Convert from a C++ object to MATLAB
template
<
typename
T
>
matlab_object
&
operator
=
(
const
T
&
new_val
);
template
<
typename
T
>
bool
try_get
(
T
&
item
)
const
{
try
{
get
(
item
);
return
true
;
}
catch
(
invalid_args_exception
&
)
{
return
false
;
}
}
const
void
*
get_handle
()
const
{
return
handle
;
}
/*!
ensures
- returns a pointer to the mxArray object. Might be NULL.
!*/
matlab_object
&
operator
=
(
const
matlab_object
&
)
=
delete
;
// Users shouldn't call these functions
const
void
*
release_object_to_matlab
()
{
const
void
*
temp
=
handle
;
handle
=
0
;
return
temp
;
}
void
set_object_handle
(
int
arg_idx_
,
const
void
*
sh
)
{
DLIB_CASSERT
(
!
handle
);
handle
=
sh
;
arg_idx
=
arg_idx_
;
}
private
:
const
void
*
handle
;
bool
should_free
;
int
arg_idx
;
};
// ----------------------------------------------------------------------------------------
class
matlab_struct
{
/*!
...
...
@@ -42,7 +115,8 @@ class matlab_struct
class
sub
;
public
:
matlab_struct
()
:
struct_handle
(
0
),
should_free
(
false
)
{}
matlab_struct
()
:
struct_handle
(
0
),
should_free
(
false
),
arg_idx
(
0
)
{}
matlab_struct
(
const
matlab_struct
&
)
=
delete
;
~
matlab_struct
();
const
sub
operator
[]
(
const
std
::
string
&
name
)
const
;
...
...
@@ -50,7 +124,7 @@ public:
bool
has_field
(
const
std
::
string
&
name
)
const
;
const
void
*
release_struct_to_matlab
()
{
const
void
*
temp
=
struct_handle
;
struct_handle
=
0
;
return
temp
;
}
void
set_struct_handle
(
const
void
*
sh
)
{
struct_handle
=
sh
;
}
void
set_struct_handle
(
int
arg_idx_
,
const
void
*
sh
)
{
DLIB_CASSERT
(
!
struct_handle
);
struct_handle
=
sh
;
arg_idx
=
arg_idx_
;
}
private
:
class
sub
...
...
@@ -72,6 +146,7 @@ private:
};
const
void
*
struct_handle
;
bool
should_free
;
int
arg_idx
;
matlab_struct
&
operator
=
(
const
matlab_struct
&
);
};
...
...
This diff is collapsed.
Click to expand it.
dlib/matlab/example_mex_function.cpp
View file @
bbe8b12d
...
...
@@ -46,6 +46,10 @@ using namespace std;
- Types corresponding to a MATLAB cell array
- a std::vector or dlib::array containing any of the above
types of objects or std::vector or dlib::array objects.
- matlab_struct and matlab_object. These are special types defined in the
call_matlab.h file and correspond to matlab structs and arbitrary matlab
objects respectively.
!*/
...
...
This diff is collapsed.
Click to expand it.
dlib/matlab/mex_wrapper.cpp
View file @
bbe8b12d
...
...
@@ -339,12 +339,6 @@ namespace mex_binding
struct
user_hit_ctrl_c
{};
struct
invalid_args_exception
{
invalid_args_exception
(
const
std
::
string
&
msg_
)
:
msg
(
msg_
)
{}
std
::
string
msg
;
};
// -------------------------------------------------------
template
<
typename
T
>
...
...
@@ -410,15 +404,13 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"Argument "
<<
arg_idx
+
1
<<
" expects a matrix with "
<<
matrix_type
::
NR
<<
" rows but got one with "
<<
src
.
nc
();
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
if
(
matrix_type
::
NC
!=
0
&&
matrix_type
::
NC
!=
src
.
nr
())
{
std
::
ostringstream
sout
;
sout
<<
"Argument "
<<
arg_idx
+
1
<<
" expects a matrix with "
<<
matrix_type
::
NC
<<
" columns but got one with "
<<
src
.
nr
();
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
...
...
@@ -453,8 +445,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"mex_function has some bug in it related to processing input argument "
<<
arg_idx
+
1
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
...
...
@@ -475,8 +466,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"Error, input argument "
<<
arg_idx
+
1
<<
" must be a non-negative number."
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
else
{
...
...
@@ -497,8 +487,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"mex_function has some bug in it related to processing input argument "
<<
arg_idx
+
1
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
...
...
@@ -524,8 +513,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"mex_function has some bug in it related to processing input argument "
<<
arg_idx
+
1
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
...
...
@@ -549,14 +537,14 @@ namespace mex_binding
if
(
!
mxIsCell
(
src
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a cell array"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a cell array"
;
throw
invalid_args_exception
(
sout
);
}
if
(
nr
!=
1
&&
nc
!=
1
)
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a cell array with exactly 1 row or 1 column (i.e. a row or column vector)"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a cell array with exactly 1 row or 1 column (i.e. a row or column vector)"
;
throw
invalid_args_exception
(
sout
);
}
const
long
size
=
nr
*
nc
;
...
...
@@ -572,8 +560,8 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"Error in argument "
<<
arg_idx
+
1
<<
": element "
<<
i
+
1
<<
" of cell array not the expected type.
\n
"
;
sout
<<
"
\t
"
<<
e
.
msg
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
\t
"
<<
e
.
what
()
;
throw
invalid_args_exception
(
sout
);
}
}
...
...
@@ -591,8 +579,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"mex_function has some bug in it related to processing input argument "
<<
arg_idx
+
1
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
// -------------------------------------------------------
...
...
@@ -608,8 +595,7 @@ namespace mex_binding
{
std
::
ostringstream
sout
;
sout
<<
"mex_function has some bug in it related to processing input argument "
<<
arg_idx
+
1
;
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
escape_percent
(
sout
).
c_str
());
throw
invalid_args_exception
(
sout
);
}
template
<
typename
MM
>
...
...
@@ -657,8 +643,8 @@ namespace mex_binding
mxGetNumberOfElements
(
prhs
)
!=
1
)
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a scalar"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a scalar"
;
throw
invalid_args_exception
(
sout
);
}
assign_scalar
(
arg_idx
,
arg
,
mxGetScalar
(
prhs
));
...
...
@@ -676,8 +662,8 @@ namespace mex_binding
if
(
!
(
num_dims
==
3
&&
mxGetDimensions
(
prhs
)[
2
]
==
3
&&
mxIsUint8
(
prhs
)))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a 3-D NxMx3 image matrix of uint8"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a 3-D NxMx3 image matrix of uint8"
;
throw
invalid_args_exception
(
sout
);
}
const
long
rows
=
mxGetDimensions
(
prhs
)[
0
];
...
...
@@ -689,8 +675,8 @@ namespace mex_binding
if
(
num_dims
!=
2
)
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a 2-D matrix (got a "
<<
num_dims
<<
"-D matrix)"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a 2-D matrix (got a "
<<
num_dims
<<
"-D matrix)"
;
throw
invalid_args_exception
(
sout
);
}
...
...
@@ -699,8 +685,8 @@ namespace mex_binding
if
(
!
mxIsDouble
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of doubles"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of doubles"
;
throw
invalid_args_exception
(
sout
);
}
if
(
is_column_major_matrix
<
T
>::
value
)
call_private_set_mxArray
(
arg
,
(
mxArray
*
)
prhs
);
...
...
@@ -712,8 +698,8 @@ namespace mex_binding
if
(
!
mxIsSingle
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of single/float"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of single/float"
;
throw
invalid_args_exception
(
sout
);
}
if
(
is_column_major_matrix
<
T
>::
value
)
...
...
@@ -726,8 +712,8 @@ namespace mex_binding
if
(
!
mxIsLogical
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of logical elements."
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of logical elements."
;
throw
invalid_args_exception
(
sout
);
}
DLIB_CASSERT
(
sizeof
(
mxLogical
)
==
sizeof
(
bool
),
"logical matrices are not supported by the mex wrapper when mxLogical isn't a bool."
);
...
...
@@ -738,8 +724,8 @@ namespace mex_binding
if
(
!
mxIsUint8
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint8"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint8"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
dlib
::
uint8
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -749,8 +735,8 @@ namespace mex_binding
if
(
!
mxIsInt8
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of int8"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of int8"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
dlib
::
int8
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -761,8 +747,8 @@ namespace mex_binding
if
(
!
mxIsInt16
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of int16"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of int16"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -773,8 +759,8 @@ namespace mex_binding
if
(
!
mxIsUint16
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint16"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint16"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -786,8 +772,8 @@ namespace mex_binding
if
(
!
mxIsInt32
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of int32"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of int32"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -799,8 +785,8 @@ namespace mex_binding
if
(
!
mxIsUint32
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint32"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint32"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -812,8 +798,8 @@ namespace mex_binding
if
(
!
mxIsUint64
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint64"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of uint64"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
...
...
@@ -825,16 +811,15 @@ namespace mex_binding
if
(
!
mxIsInt64
(
prhs
)
||
mxIsComplex
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a matrix of int64"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a matrix of int64"
;
throw
invalid_args_exception
(
sout
);
}
assign_mat
(
arg_idx
,
arg
,
pointer_to_matrix
((
const
type
*
)
mxGetData
(
prhs
),
nc
,
nr
));
}
else
{
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
"mex_function uses unsupported matrix type"
);
throw
invalid_args_exception
(
"mex_function uses unsupported matrix type"
);
}
}
else
if
(
is_array_type
<
T
>::
value
)
...
...
@@ -847,15 +832,14 @@ namespace mex_binding
if
(
!
mxIsClass
(
prhs
,
"function_handle"
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a function handle."
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a function handle."
;
throw
invalid_args_exception
(
sout
);
}
assign_function_handle
(
arg_idx
,
arg
,
prhs
);
}
else
{
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
"mex_function uses unsupported input argument type"
);
throw
invalid_args_exception
(
"mex_function uses unsupported input argument type"
);
}
}
...
...
@@ -868,11 +852,21 @@ namespace mex_binding
if
(
!
mxIsStruct
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a struct"
;
throw
invalid_args_exception
(
sout
.
str
());
sout
<<
"Input argument "
<<
arg_idx
+
1
<<
" must be a struct"
;
throw
invalid_args_exception
(
sout
);
}
arg
.
set_struct_handle
(
arg_idx
,
prhs
);
}
arg
.
set_struct_handle
(
prhs
);
void
validate_and_populate_arg
(
long
arg_idx
,
const
mxArray
*
prhs
,
matlab_object
&
arg
)
{
arg
.
set_object_handle
(
arg_idx
,
prhs
);
}
...
...
@@ -885,8 +879,8 @@ namespace mex_binding
if
(
!
mxIsChar
(
prhs
))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" must be a char string"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" must be a char string"
;
throw
invalid_args_exception
(
sout
);
}
const
long
nr
=
mxGetM
(
prhs
);
...
...
@@ -896,8 +890,8 @@ namespace mex_binding
if
(
mxGetString
(
prhs
,
&
arg
[
0
],
arg
.
size
()))
{
std
::
ostringstream
sout
;
sout
<<
" argument "
<<
arg_idx
+
1
<<
" encountered an error while calling mxGetString()"
;
throw
invalid_args_exception
(
sout
.
str
()
);
sout
<<
"
Input
argument "
<<
arg_idx
+
1
<<
" encountered an error while calling mxGetString()"
;
throw
invalid_args_exception
(
sout
);
}
arg
.
resize
(
size
);
}
...
...
@@ -1133,6 +1127,14 @@ namespace mex_binding
plhs
=
(
mxArray
*
)
item
.
release_struct_to_matlab
();
}
void
assign_to_matlab
(
mxArray
*&
plhs
,
matlab_object
&
item
)
{
plhs
=
(
mxArray
*
)
item
.
release_object_to_matlab
();
}
void
assign_to_matlab
(
mxArray
*&
plhs
,
const
std
::
string
&
item
...
...
@@ -2714,6 +2716,14 @@ namespace mex_binding
}
};
// ----------------------------------------------------------------------------------------
template
<
typename
T
>
struct
is_matlab_object
{
const
static
bool
value
=
false
;
};
template
<>
struct
is_matlab_object
<
matlab_object
>
{
const
static
bool
value
=
true
;
};
template
<>
struct
is_matlab_object
<
const
matlab_object
>
{
const
static
bool
value
=
true
;
};
template
<>
struct
is_matlab_object
<
matlab_object
&>
{
const
static
bool
value
=
true
;
};
template
<>
struct
is_matlab_object
<
const
matlab_object
&>
{
const
static
bool
value
=
true
;
};
// ----------------------------------------------------------------------------------------
template
<
...
...
@@ -2929,12 +2939,36 @@ namespace mex_binding
#endif
// Arguments with type matlab_object are optional in both input and output.
int
num_optional_inputs
=
0
;
int
num_optional_outputs
=
0
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg20_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg20_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg19_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg19_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg18_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg18_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg17_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg17_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg16_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg16_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg15_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg15_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg14_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg14_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg13_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg13_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg12_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg12_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg11_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg11_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg10_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg10_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg9_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg9_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg8_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg8_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg7_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg7_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg6_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg6_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg5_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg5_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg4_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg4_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg3_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg3_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg2_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg2_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
if
(
is_matlab_object
<
typename
sig_traits
<
funct
>::
arg1_type
>::
value
)
if
(
is_input_type
<
typename
sig_traits
<
funct
>::
arg1_type
>::
value
)
++
num_optional_inputs
;
else
++
num_optional_outputs
;
/* check for proper number of arguments */
if
(
nrhs
>
expected_nrhs
||
nrhs
<
expected_nrhs
-
defaulted_args
)
if
(
nrhs
>
expected_nrhs
||
nrhs
<
expected_nrhs
-
defaulted_args
-
num_optional_inputs
)
{
std
::
ostringstream
sout
;
sout
<<
"Expected between "
<<
expected_nrhs
-
defaulted_args
sout
<<
"Expected between "
<<
expected_nrhs
-
defaulted_args
-
num_optional_inputs
<<
" and "
<<
expected_nrhs
<<
" input arguments, got "
<<
nrhs
<<
"."
;
mexErrMsgIdAndTxt
(
"mex_function:nrhs"
,
...
...
@@ -3133,7 +3167,7 @@ namespace mex_binding
catch
(
invalid_args_exception
&
e
)
{
throw
dlib
::
error
(
"Error occurred calling MATLAB function '"
+
function_name
+
"' from mex file.
\n
"
"The MATLAB function didn't return what we expected it to.
\n
In particular, return"
+
e
.
msg
);
"The MATLAB function didn't return what we expected it to.
\n
In particular, return"
+
string
(
e
.
what
())
);
}
}
...
...
@@ -4369,6 +4403,54 @@ namespace dlib
free_callback_resources
<
T1
>
(
nlhs
,
plhs
,
nrhs
,
prhs
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
matlab_object
::~
matlab_object
(
)
{
if
(
handle
&&
should_free
)
{
mxDestroyArray
((
mxArray
*
)
handle
);
handle
=
0
;
}
}
template
<
typename
T
>
matlab_object
::
operator
T
(
)
const
{
T
item
;
get
(
item
);
return
item
;
}
template
<
typename
T
>
void
matlab_object
::
get
(
T
&
item
)
const
{
if
(
handle
==
0
)
throw
dlib
::
invalid_args_exception
(
"An attempt was made to access an empty matlab_object."
);
mex_binding
::
validate_and_populate_arg
(
arg_idx
,(
mxArray
*
)
handle
,
item
);
}
template
<
typename
T
>
matlab_object
&
matlab_object
::
operator
=
(
const
T
&
new_val
)
{
mxArray
*
item
;
mex_binding
::
assign_to_matlab
(
item
,
new_val
);
handle
=
item
;
should_free
=
true
;
return
*
this
;
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
...
@@ -4398,7 +4480,7 @@ namespace dlib
{
std
::
ostringstream
sout
;
sout
<<
"Struct field '"
<<
mxGetFieldNameByNumber
((
const
mxArray
*
)
struct_handle
,
field_idx
)
<<
"' can't be interpreted as the requested type."
<<
endl
<<
e
.
msg
;
<<
endl
<<
e
.
what
()
;
throw
dlib
::
error
(
sout
.
str
());
}
}
...
...
@@ -5013,7 +5095,7 @@ void mexFunction( int nlhs, mxArray *plhs[],
catch
(
mex_binding
::
invalid_args_exception
&
e
)
{
mexErrMsgIdAndTxt
(
"mex_function:validate_and_populate_arg"
,
mex_binding
::
escape_percent
(
"Input"
+
e
.
msg
).
c_str
());
mex_binding
::
escape_percent
(
e
.
what
()
).
c_str
());
}
catch
(
mex_binding
::
user_hit_ctrl_c
&
)
{
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment