C++ decode void pointer nicely for Matlab mex
I'm trying to write a C++ mex function for Matlab that can handle multiple datatypes. Matlab gives me an mxArray*
, from which I can retrieve a void*
for the data, and an mxClassID
telling me the datatype. So I can do something like:
void *data = mxGetData(mxarray);
switch (mxGetClassID(mxarray)) {
case mxDOUBLE_CLASS:
my_function(static_cast<double *>(data));
...
my_function
is templated, so this handles different datatypes nicely. But it's still very annoying to need to have this switch for every possible my_function1
, my_function2
, etc.
So far, the solution I've come up with is to use a functional approach and have a method that accepts a functor:
template <typename ReturnType, typename FunctorType>
ReturnType mxarr_apply(const mxArray *inarr, FunctorType functor) {
void *data = mxGetData(inarr);
switch (mxGetClassID(inarr)) {
case mxDOUBLE_CLASS:
return (ReturnType) functor(static_cast<double *>(data));
...
This way I can put my logic in the functor (with operator()
templated) and not have to recreate the switch over and over.
But I wonder if there is some other way? In Java I think I could just have a function that translates the mxClassID
directly into a class
reference that could then be used to instanti开发者_开发百科ate a type flexibly at runtime, but this doesn't seem to be an option in C++.
You're correct. There's no way in C++ to get a class reference at runtime. You have to write the switch, at least once.
If you face the need to write multiple switches you might want to either hide it's logic into a factory, that would return the right functor given the type
void *data = mxGetData(mxarray);
functor func = FunctorFactory::Get(mxGetClassID(mxarray));
func (reinterpret_cast<double*>(data));
or simply create a map (preferrably unordered or a hash) of types to functors.
void *data = mxGetData(mxarray);
functor func = functorMap[mxGetClassID(mxarray)]; // need to check for key availability
func (reinterpret_cast<double*>(data));
精彩评论