Using mex and clibgen

6 Ansichten (letzte 30 Tage)
Jonas Steiner
Jonas Steiner am 31 Jan. 2022
Bearbeitet: Jonas Steiner am 18 Feb. 2022
When using a shared library in matlab, that uses structs as data types they will be included in the library definition as classes.
% Example C code
%
% ...
%
% struct dummy
% {
% ...
% };
%
% double doSomething(dummy* handle)
% {
% ...
% }
clibgen.generateLibraryDefinition('example.dll')
Error using clibgen.generateLibraryDefinition (line 189)
Unable to open 'example.dll'.
summary(defineexample)
% Console output:
% Class clib.example.dummy
%
% Constructors:
% clib.example.dummy()
% clib.example.dummy(clib.example.dummy)
%
% No Methods defined
% No Properties defined
%
% Functions
% double clib.example.doSomething(clib.example.dummy)
So MATLAB basically creates a matlab class in the well known style from the struct out of the dll.
Does anyone know how i get back to the original class/struct when calling a mex function?
Or even if you know how exactly matlab converts this struct to a class would be helpfull.
For example:
dummy could be a collection of user data contained in a struct. A pointer to an instance of that struct is passed to a function inside the dll. Of course there are no pointers in MATLAB so an instance of the newly created (handle?) class will be used as the argument to the function generated by clibgen.
When i now pass that instance of the matlab class to a mex function is there a way of retreiving the original type 'dummy' from the object of type clib.example.dummy?
  1 Kommentar
Jonas Steiner
Jonas Steiner am 18 Feb. 2022
Bearbeitet: Jonas Steiner am 18 Feb. 2022
My problem was, that the importet class contains properties of the unsupported type void* (property named "d" in the example).
I can not edit the source library file as it is owned by a third party.
%in shared library
...
struct data
{
void* d;
};
When i pass this object to c++ code using the c++ mex interface i retrieve an input argument of type HANDLE_OBJ_REF.
%in example.cpp C++-mex source file
...
class MexFunction : public matlab::mex::Function
{
public:
void operator()(ArgumentList outputArgs, ArgumentList inputArgs)
{
std::shared_ptr<matlab::engine::MATLABEngine> engine = getEngine();
...
if (inputArgs[0].getType() != ArrayType::HANDLE_OBJECT_REF)
{
sprintf(errorStr, "wrong type (%d)", (int)(inputArgs[1].getType()));
matlabPtr->feval(u"error", 0, std::vector<Array>({ factory.createScalar(errorStr) }));
}
matlab::data::Array obj = std::move(inputArgs[0]);
matlab::data::Array dataPropertyArray = engine.getProperty(obj, std::string("d"));
void* dataProperty = TypedArray<void*>(std::move(deviceArray))[0];
}
}
obviously this does not work since matlab did not support the property of type void* when converting "data". obj does not have a property named "d".
Also there is no typedArray of unsupported types.
However in my case i could pass the pointer "d" of the element "data" to MATLAB as an unsigned 64 bit integer and work my way around that way.
Maybe one could also work with a pointer to "data" itself in a similar way to make MATLAB able to communicate unsupported types.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Benjamin Thompson
Benjamin Thompson am 31 Jan. 2022
See the article "Define MATLAB Interface for C++ Library" for a description of the MATLAB library definition process along with an example you can work. A struct is a simpler example than a C++ class. For your code above to work, there must be an example.dll that is in your PATH environment variable so that MATLAB can load it. See the help on clibgen.generateLibraryDefinition, you would generally provide header files and then any third party libraries using a syntax like:
clibgen.generateLibraryDefinition("A.hpp","Libraries","A.dll")
  2 Kommentare
Jonas Steiner
Jonas Steiner am 11 Feb. 2022
This does not answer my question.
The above example does not work, because it is a dummy example.
I basically wanted to know what matlab does to a class when using clibgen producing a MATLAB equivalent of the class.
When passing an element of that type to a c++ mex function it can be determined, that it is of type HANDLE_OBJ_REF and passing this object to a MATLAB function using feval shows, that the object is of the correct type.
My question is: "What is the difference between the original element of the class and the HANDLE_OBJ_REF of the class, that went through MATLAB?"
Benjamin Thompson
Benjamin Thompson am 11 Feb. 2022
There should be a one to one mapping of members and methods from the C++ class to the MATLAB class, subject to the limitations in the "Related Topics" section at the bottom of that article I mentioned. For example no move constructors/assignment functions will be imported, no types greater than 64 bits long, and no pointer references. No methods using void. You may just have to try this out.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by