目录
从 C++ 调用 MATLAB 函数
调用带单一返回参数的函数
使用名称/值参数调用函数
以异步方式调用函数
使用多个返回参数调用函数
用原生 C++ 类型调用函数
控制输出的数目
使用 matlab::engine::MATLABEngine 类的 feval 和 fevalAsync 成员函数从 C++ 调用 MATLAB® 函数。当要将函数参数从 C++ 传递给 MATLAB 和将函数执行的结果返回给 C++ 时,请使用这些函数。这些成员函数的工作方式类似于 MATLAB feval 函数。
要调用 MATLAB 函数,需要满足以下条件:
将函数名称作为 matlab::engine::String 传递。
定义 MATLAB 函数所需的输入参数。可以使用原生 C++ 数据类型或 MATLAB 数据 API。有关详细信息,可以参考MATLAB 数据 API。
指定 MATLAB 函数应提供的输出的数目。默认为一个输出。有关详细信息,可以参考使用多个返回参数调用函数和控制输出的数目。
为 MATLAB 函数的结果定义适当的返回类型。
使用流缓冲区将标准输出和标准错误从 MATLAB 命令行窗口重定向到 C++。有关详细信息,可以参考Redirect MATLAB Command Window Output to C++
此示例使用 MATLAB gcd函数求两个数值的最大公约数。MATLABEngine::feval 成员函数返回 gcd 函数调用的结果。使用 matlab::data::ArrayFactory 创建两个标量 int16_t 参数。将参数以 std::vector 形式传递给 MATLABEngine::feval。
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"
#include
void callFevalgcd() {
// Pass vector containing MATLAB data array scalar
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
// Create MATLAB data array factory
matlab::data::ArrayFactory factory;
// Pass vector containing 2 scalar args in vector
std::vector args({
factory.createScalar(30),
factory.createScalar(56) });
// Call MATLAB function and return result
matlab::data::TypedArray result = matlabPtr->feval(u"gcd", args);
int16_t v = result[0];
std::cout << "Result: " << v << std::endl;
}
可以使用原生 C++ 类型调用 MATLABEngine::feval。为此,必须将调用 MATLABEngine::feval 的返回类型指定为:
feval(...)
例如,此处返回类型是 int:
int cresult = matlabPtr->feval(u"gcd", 30, 56);
此示例定义一个 matlab::data::TypedArray,以将 double 类型的数组传递给 MATLAB sqrt 函数。由于数组中的数值之一是负数,因此 MATLAB 返回复数数组作为结果。因此,将返回类型定义为 matlab::data::TypedArray
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include
void callFevalsqrt() {
// Call MATLAB sqrt function on array
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
// Create MATLAB data array factory
matlab::data::ArrayFactory factory;
// Define a four-element array
matlab::data::TypedArray const argArray =
factory.createArray({ 1,4 }, { -2.0, 2.0, 6.0, 8.0 });
// Call MATLAB function
matlab::data::TypedArray> 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;
}
}
在调用 MATLAB 函数时,对返回类型使用 matlab::data::Array 是安全的。例如,可以对返回值使用 matlab::data::Array 来编写前面的示例。
void callFevalsqrt() {
// Call MATLAB sqrt function on array
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr 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 v = results[i];
double realPart = v.real();
double imgPart = v.imag();
std::cout << "Square root of " << a << " is " <<
realPart << " + " << imgPart << std::endl;
}
}
一些 MATLAB 函数接受可选的名称-值对组参数。名称是字符数组,值可以是任何类型的值。使用 std::vector 创建包含正确序列的名称和值的参数向量。此示例代码调用 MATLAB movsum 函数来计算行向量的三点中心移动和,而放弃端点计算。此函数调用需要以下参数:
数值数组
标量窗口长度
名称-值对组由字符数组 Endpoint 和 discard 组成
以下是等效的 MATLAB 代码:
A = [4 8 6 -1 -2 -3 -1 3 4 5];
M = movsum(A,3,'Endpoints','discard');
将这些要用于 MATLAB 函数的参数以 std::vector 形式传递给 MATLABEngine::feval。使用 matlab::data::ArrayFactory 创建每个参数。
void callFevalmovsum() {
//Pass vector containing various types of arguments
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
// Create MATLAB data array factory
matlab::data::ArrayFactory factory;
// Create a vector of input arguments
std::vector args({
factory.createArray({ 1, 10 }, { 4, 8, 6, -1, -2, -3, -1, 3, 4, 5 }),
factory.createScalar(3),
factory.createCharArray("Endpoints"),
factory.createCharArray("discard")
});
// Call MATLAB function
matlab::data::TypedArray const result = matlabPtr->feval(u"movsum", args);
// Display results
int i = 0;
for (auto r : result) {
std::cout << "results[" << i++ << "] = " << r << std::endl;
}
}
此示例调用 MATLAB conv函数来将两个多项式相乘。在调用 MATLABEngine::fevalAsync 后,使用 FutureResult::get 从 MATLAB 获得结果。
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include
static void callFevalAsync() {
//Call MATLAB functions asynchronously
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
// Create MATLAB data array factory
matlab::data::ArrayFactory factory;
// Create input argument arrays
std::vector args({
factory.createArray({ 1, 3 },{ 1, 0, 1 }),
factory.createArray({ 1, 2 },{ 2, 7 })
});
String func(u"conv");
// Call function asnychronously
FutureResult future = matlabPtr->fevalAsync(func, args);
// Get results
matlab::data::TypedArray results = future.get();
// Display results
std::cout << "Coefficients: " << std::endl;
for (auto r : results) {
std::cout << r << " " << std::endl;
}
}
以下示例代码使用 MATLAB gcd函数对传递的两个数值输入求最大公约数和 Bézout 系数。gcd 函数可以返回一个或三个参数,具体取决于函数调用请求的输出的数目。在此示例中,对 MATLAB gcd函数的调用返回三个输出。
默认情况下,MATLABEngine::feval 假设返回值的数目为1。因此,必须将返回值的实际数目指定为 MATLABEngine::feval 的第二个参数。在此示例中,MATLABEngine::feval 返回一个 std::vector,其中包含 gcd 函数调用的三个结果。返回值是整数标量。
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include
void multiOutput() {
//Pass vector containing MATLAB data array array
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr 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 args({
factory.createScalar(30),
factory.createScalar(56)
});
//Call gcd function, get 3 outputs
const size_t numReturned = 3;
std::vector result = matlabPtr->feval(u"gcd", numReturned, args);
//Display results
for (auto r : result) {
std::cout << "gcd output: " << int16_t(r[0]) << std::endl;
}
}
调用 MATLAB 函数时,可以使用原生 C++ 类型。MATLABEngine::feval 和 MATLABEngine::fevalAsync 接受作为 MATLAB 函数参数传递的某些标量 C++ 类型。要将数组和其他类型传递给 MATLAB 函数,可以使用MATLAB 数据 API。
此示例使用 int16_t 值作为输入,使用 std::tuple 从 MATLAB gcd 函数返回结果。以下是等效的 MATLAB 代码。
[G,U,V] = gcd(int16(30),int16(56));
#include "MatlabEngine.hpp"
#include
#include
void multiOutputTuple() {
//Return tuple from MATLAB function call
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
//Call MATLAB gcd function
std::tuple nresults;
nresults = matlabPtr->feval>
(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;
}
根据请求的输出数量,MATLAB 函数的行为可能会有所不同。某些函数不返回任何输出或返回指定数量的输出。
例如,MATLAB pause函数使执行暂停指定的秒数。但是,如果使用一个输出参数调用pause,它将立即返回状态值而不存在暂停。
pause(20) % Pause for 20 seconds
state = pause(20); % No pause, return pause state
此示例调用 pause 但不指定输出。指定 void 输出后,MATLAB 暂停执行 20 秒。
#include "MatlabEngine.hpp"
void voidOutput() {
// No output from feval
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
// Call pause function with no output
matlabPtr->feval(u"pause", 20);
}
对 MATLABEngine::feval 的以下调用使用将 MATLAB函数参数定义为 std::vector
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
void zeroOutput() {
// No output from feval
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr matlabPtr = startMATLAB();
//Create MATLAB data array factory
matlab::data::ArrayFactory factory;
// Call pause function with no output
matlab::data::Array arg = factory.createScalar(20);
const size_t numReturned = 0;
matlabPtr->feval(u"pause", numReturned, { arg });
}
MATLAB clock函数将当前日期和时间作为日期向量返回。如果指定两个输出,clock 会以布尔值形式返回第二个输出,指示它是否为系统时区的夏令时。
此示例调用带一个输出或两个输出的 clock 函数,具体取决于输入参数的值。传递给 MATLABEngine::feval 调用的第二个参数决定从 clock 请求的输出的数目。
使用这些参数调用 MATLABEngine::feval。
输入
MATLAB 函数名称 | const matlab::engine::String |
输出数量 | const size_t |
MATLAB 函数的输入参数(空) | std::vector |
输出
所有输出 | std::vector |
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include
void varOutputs(const bool tZone) {
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr 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 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;
}
}
}