This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Call MATLAB Functions from C++

Call MATLAB® functions from C++ using the feval and fevalAsync member functions of the matlab::engine::MATLABEngine class. Use these functions when you want to pass function arguments from C++ to MATLAB and to return the result of the function execution to C++. These member functions work like the MATLAB feval function.

To call a MATLAB function:

  • Pass the function name as a matlab::engine::String.

  • Define the input arguments required by the MATLAB function. You can use either native C++ data types or the MATLAB Data API. For more information, see MATLAB Data API.

  • Specify the number of outputs expected from the MATLAB function. One output is the default. For more information, see Call Function with Multiple Returned Arguments and Control Number of Outputs.

  • Define the appropriate returned type for the results of the MATLAB function.

  • Use stream buffers to redirect standard output and standard error from the MATLAB command window to C++. For more information, see Redirect MATLAB Command Window Output to C++

To evaluate MATLAB statements using variables in the MATLAB base workspace, use the matlab::engine::MATLABEngine eval and evalAsync member functions. These functions enable you to create and use variables in the MATLAB workspace, but do not return values. For more information, see Evaluate MATLAB Statements from C++.

For information on how to setup and build C++ engine programs, see Build C++ Engine Programs.

Call Function with Single Returned Argument

This example uses the MATLAB gcd function to find the greatest common divisor of two numbers. The MATLABEngine::feval member function returns the results of the gcd function call.

Use the matlab::data::ArrayFactory to create two scalar int16_t arguments. Pass the arguments to MATLABEngine::feval in a std::vector.

#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include <iostream>
void callFevalgcd() {

    // Pass vector containing MATLAB data array scalar
    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Create MATLAB data array factory
    matlab::data::ArrayFactory factory;

    // Pass vector containing 2 scalar args in vector    
    std::vector<matlab::data::Array> args({
        factory.createScalar<int16_t>(30),
        factory.createScalar<int16_t>(56) });

    // Call MATLAB function and return result
    matlab::data::TypedArray<int16_t> result = matlabPtr->feval(u"gcd", args);
    int16_t v = result[0];
    std::cout << "Result: " << v << std::endl;
}

You can call MATLABEngine::feval using native C++ types. To do so, you must specify the returned type with the call to MATLABEngine::feval as:

feval<type>(...)

For example, the returned type is int here:

int cresult = matlabPtr->feval<int>(u"gcd", 30, 56);

This example defines a matlab::data::TypedArray to pass an array of type double to the MATLAB sqrt function. Because one of the numbers in the array is negative, MATLAB returns a complex array as the result. Therefore, define the returned type as a matlab::data::TypedArray<std::complex<double>>.

#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
void callFevalsqrt() {
    // Call MATLAB sqrt function on array

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Create  MATLAB data array factory
    matlab::data::ArrayFactory factory;

    // Define a four-element array 
    matlab::data::TypedArray<double> const argArray = 
        factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 });

    // Call MATLAB function
    matlab::data::TypedArray<std::complex<double>> const results = 
        matlabPtr->feval(u"sqrt", argArray);

    // Display results
    int i = 0;
    for (auto r : results) {
        double a = argArray[i++];
        double realPart = r.real();
        double imgPart = r.imag();
        std::cout << "Square root of " << a << " is " << 
            realPart << " + " << imgPart << "i" << std::endl;
    }
}

It is safe to use a matlab::data::Array for returned types when calling MATLAB functions. For example, you can write the previous example using a matlab::data::Array for the returned value.

void callFevalsqrt() {
    // Call MATLAB sqrt function on array

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Create MATLAB data array factory
    matlab::data::ArrayFactory factory;

    // Define a four-element array 
    matlab::data::Array const argArray = 
        factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 });

    // Call MATLAB function    
    matlab::data::Array results = matlabPtr->feval(u"sqrt", argArray);

    // Display results 
    for (int i = 0; i < results.getNumberOfElements(); i++) {
        double a = argArray[i];
        std::complex<double> v = results[i];
        double realPart = v.real();
        double imgPart = v.imag();
        std::cout << "Square root of " << a << " is " <<
            realPart << " + " << imgPart << std::endl;
    }
}

Call Function with Name/Value Arguments

Some MATLAB functions accept optional name-value pair arguments. The names are character arrays and the values can be any type of value. Use a std::vector to create a vector of arguments containing the names and values in correct sequence.

This sample code calls the MATLAB movsum function to compute the three-point centered moving sum of a row vector, discarding endpoint calculations. This function call requires these arguments:

  • Numeric array

  • Scalar window length

  • Name-value pair consisting of the character arrays Endpoint and discard

Here is the equivalent MATLAB code:

A = [4 8 6 -1 -2 -3 -1 3 4 5];
M = movsum(A,3,'Endpoints','discard');

Pass the arguments to MATLABEngine::feval as a std::vector containing these arguments for the MATLAB function. Create each argument using the matlab::data::ArrayFactory.

void callFevalmovsum() {
    //Pass vector containing various types of arguments

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Create  MATLAB data array factory
    matlab::data::ArrayFactory factory;

   // Create a vector of input arguments
    std::vector<matlab::data::Array> args({
        factory.createArray<double>({ 1, 10 }, { 4, 8, 6, -1, -2, -3, -1, 3, 4, 5 }),
        factory.createScalar<int32_t>(3),
        factory.createCharArray("Endpoints"),
        factory.createCharArray("discard")
    });

    // Call MATLAB function 
    matlab::data::TypedArray<double> const result = matlabPtr->feval(u"movsum", args);

    // Display results    
    int i = 0;
    for (auto r : result) {
        std::cout << "results[" << i++ << "] = " << r << std::endl;
    }
}

Call Function Asynchronously

This example calls the MATLAB conv function to multiply two polynomials. After calling MATLABEngine::fevalAsync, use FutureResult::get to get the result from MATLAB.

#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
static void callFevalAsync() {
    //Call MATLAB functions asynchronously

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Create MATLAB data array factory
    matlab::data::ArrayFactory factory;

     // Create input argument arrays
    std::vector<matlab::data::Array> args({
        factory.createArray<double>({ 1, 3 },{ 1, 0, 1 }),
        factory.createArray<double>({ 1, 2 },{ 2, 7 }) 
    });
    String func(u"conv");

    // Call function asnychronously
    FutureResult<matlab::data::Array> future = matlabPtr->fevalAsync(func, args);
    
    // Get results
    matlab::data::TypedArray<double> results = future.get();

    // Display results
    std::cout << "Coefficients: " << std::endl;
    for (auto r : results) {
        std::cout << r << " " << std::endl;
    }
}

Call Function with Multiple Returned Arguments

This sample code uses the MATLAB gcd function to find the greatest common divisor and Bézout coefficients from the two numeric values passes as inputs. The gcd function can return either one or three arguments, depending on how many outputs the function call requests. In this example, the call to the MATLAB gcd function returns three outputs.

By default, MATLABEngine::feval assumes that the number of returned values is one. Therefore, you must specify the actual number of returned values as the second argument to MATLABEngine::feval.

In this example, MATLABEngine::feval returns a std::vector containing the three results of the gcd function call. The returned values are scalar integers.

#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
void multiOutput() {
    //Pass vector containing MATLAB data array array

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
    std::cout << "Started MATLAB Engine" << std::endl;

    //Create MATLAB data array factory
    matlab::data::ArrayFactory factory;

    //Create vector of MATLAB data array arrays
    std::vector<matlab::data::Array> args({
        factory.createScalar<int16_t>(30),
        factory.createScalar<int16_t>(56)
    });

    //Call gcd function, get 3 outputs
    const size_t numReturned = 3;
    std::vector<matlab::data::Array> result = matlabPtr->feval(u"gcd", numReturned, args);

    //Display results
    for (auto r : result) {
        std::cout << "gcd output: " << int16_t(r[0]) << std::endl;
    }
}

Call Function with Native C++ Types

You can use native C++ types when calling MATLAB functions. MATLABEngine::feval and MATLABEngine::fevalAsync accept certain scalar C++ types passed as MATLAB function arguments. To pass arrays and other types to MATLAB functions, use the MATLAB Data API. For more information on this API, see MATLAB Data API.

This example uses int16_t values as inputs and a std::tuple to return the results from the MATLAB gcd function.

Here is the equivalent MATLAB code.

[G,U,V] = gcd(int16(30),int16(56));
#include "MatlabEngine.hpp"
#include <iostream>
#include <tuple>
void multiOutputTuple() {
    //Return tuple from MATLAB function call

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    //Call MATLAB gcd function    
    std::tuple<int16_t, int16_t, int16_t> nresults;
    nresults = matlabPtr->feval<std::tuple<int16_t, int16_t, int16_t>>
        (u"gcd", int16_t(30), int16_t(56));

    // Display results
    int16_t G;
    int16_t U;
    int16_t V;
    std::tie(G, U, V) = nresults;
    std::cout << "GCD : " << G << ", "
              << "Bezout U: " << U << ", "
              << "Bezout V: " << V << std::endl;
}

For specific information on member function syntax, see matlab::engine::MATLABEngine.

Control Number of Outputs

MATLAB functions can behave differently depending on the number of outputs requested. Some functions can return no outputs or a specified number of outputs.

For example, the MATLAB pause function holds execution for a specified number of seconds. However, if you call pause with an output argument, it returns immediately with a status value without pausing.

pause(20) % Pause for 20 seconds
state = pause(20); % No pause, return pause state

This example calls pause without assigning an output. With void output specified, MATLAB pauses execution for 20 seconds.

#include "MatlabEngine.hpp"
void voidOutput() {
    // No output from feval
    using namespace matlab::engine;

    // Start MATLAB engine synchronously    
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    // Call pause function with no output    
    matlabPtr->feval<void>(u"pause", 20); 
}

This call to MATLABEngine::feval uses the signature that defines the MATLAB function arguments as a std::vector<matlab::data::Array>. Without assigning an output argument, MATLAB pauses execution for 20 seconds.

#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
void zeroOutput() {
    // No output from feval

    using namespace matlab::engine;

    // Start MATLAB engine synchronously    
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();

    //Create MATLAB data array factory
    matlab::data::ArrayFactory factory;

    // Call pause function with no output    
    matlab::data::Array arg = factory.createScalar<int16_t>(20);
    const size_t numReturned = 0;
    matlabPtr->feval(u"pause", numReturned, { arg }); 
}

The MATLAB clock function returns the current date and time as a date vector. If you assign two outputs, clock returns the second output as a Boolean value indicating if it is Daylight Saving Time in the system time zone.

This example calls the clock function with one output or two outputs, depending on the value of an input argument. The second argument passed to the call to MATLABEngine::feval determines how many outputs to request from clock.

Call MATLABEngine::feval with these arguments.

Inputs

MATLAB function nameconst matlab::engine::String
Number of outputsconst size_t
Input arguments for MATLAB function (empty)std::vector<matlab::data::Array>

Outputs

All outputs std::vector<matlab::data::Array>
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
void varOutputs(const bool tZone) {

    using namespace matlab::engine;

    // Start MATLAB engine synchronously
    std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
    std::cout << "Started MATLAB Engine" << std::endl;

    // Define number of outputs
    size_t numReturned(0);
    if (tZone) {
        numReturned = 2;
    } else {
        numReturned = 1;
    }
    std::vector<matlab::data::Array> dateTime = matlabPtr->feval(u"clock", numReturned, { });
    auto dateVector = dateTime[0];

    // Display results
    for (int i = 0; i < 6; i++) {
        std::cout << double(dateVector[i]) << " ";
    }

    if (tZone) {
        auto DTS = dateTime[1];
        if (bool(DTS[0])) {
            std::cout << "It is Daylight Saving Time" << std::endl;
        }
        else {
          std::cout << "It is Standard Time" << std::endl;
        }
    }
}

See Also

|

Related Topics