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
7bf01102
Commit
7bf01102
authored
Dec 25, 2016
by
Davis King
Browse files
Options
Browse Files
Download
Plain Diff
merged
parents
fdbb3b12
1cdbcb5a
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 @
7bf01102
...
...
@@ -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
&
);
};
...
...
dlib/matlab/example_mex_function.cpp
View file @
7bf01102
...
...
@@ -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.
!*/
...
...
dlib/matlab/mex_wrapper.cpp
View file @
7bf01102
...
...
@@ -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
&
)
{
...
...
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