Is it possible to pass functions as arguments to C++ MEX functions?

6 ビュー (過去 30 日間)
thomas greenhill
thomas greenhill 2021 年 2 月 12 日
回答済み: thomas greenhill 2021 年 2 月 13 日
I have only been working with mex functions for a couple of weeks, and am now working on writing a Runge-Kutta, 4th order solver as a C++ mex function.
I am wondering whether it is possible to take a function as an input.
Effectively, it would be nice to have my dynamics function written in MATLAB and pass it straight through to my RK4 mex function.
For example, if the dynamics are governed by Duffing's equation:
function xdot = Duffing(t,x)
xdot = [x(2); 0.3*cos(t)-0.22*x(2)+x(1)-x(1)^3];
end
(I do realize this can be written in line as Duffing = @(t,x) (whatever) also.
Is there a way to call the dynamics function from within a mex function or is inputs[] constrained to numeric types only?
I tried the following:
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
// Access the dynamics function
typedef TypedArray<double> xdot_type (TypedArray<double>, TypedArray<double>);
xdot_type xdot;
xdot = inputs[0];
Naturally, this doesn't work because inputs[0] is not assignable to 'TypedArray<double> (TypedArray<double>, TypedArray<double>)', since I think the ArgumentList thinks inputs[0] should be purely numeric.
Can anyone think of a solution to this, or will I just have to write my dynamics function in C++?
Looking forward to some suggestions!
Thomas
  1 件のコメント
James Tursa
James Tursa 2021 年 2 月 12 日
In C one would just use mexCallMATLAB with the function name as a string, or with the function handle passed in and mexCallMATLAB using 'feval'. I am not familiar enough with the C++ interface to know how this might work with ArgumentList types.

サインインしてコメントする。

採用された回答

James Tursa
James Tursa 2021 年 2 月 12 日
編集済み: James Tursa 2021 年 2 月 12 日
Just quickly skimming the MATLAB C++ API doc, it looks like you can do this using the matlab::engine::MATLABEngine::feval interface found here:
I.e., pass your function name into the C++ mex file as a string which you can get from the ArgumentList via the matlab::data::CharArray syntax:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
matlab::data::CharArray fname = inputs[0];
etc.
Then convert fname into a std::u16string and use that in the feval interface.

その他の回答 (1 件)

thomas greenhill
thomas greenhill 2021 年 2 月 13 日
James, many thanks for your suggestion, this did indeed work.
The full solution for anyone looking at this in the future is:
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs)
{
matlab::data::CharArray fn = inputs[0];
std::basic_string<char16_t> fname = fn.toUTF16();
std::vector<matlab::data::Array> args({...whatever other inputs...});
matlab::data::Array result;
result = matlabPtr->feval(fname, args);
matlab::data::TypedArray<double> returnedValues(std::move(result));
...whatever outputs... = returnedValues;
}

カテゴリ

Help Center および File ExchangeMATLAB Compiler についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by