Функции MEX, которые подключаются к внешним ресурсам, таким как сокеты, датчики, файлы и базы данных, должны управлять этими ресурсами. Поскольку функции C++ MEX реализуются как классы, можно определить функции конструктора и деструктора для управления этими ресурсами и переменными, которые сохраняются при повторных вызовах функции MEX.
При вызове функции MEX MATLAB ® создает экземпляр MexFunction класс. Этот объект сохраняется для сеанса MATLAB или до тех пор, пока объект не будет очищен с помощью clear
mex команда. Повторные вызовы функции MEX могут обрабатывать входящие данные и освобождать ресурсы по завершении.
Эта функция MEX открывает текстовый файл и считывает одно слово при каждом вызове функции. MexFunction класс, реализующий функцию MEX, определяет конструктор и деструктор для открытия и закрытия файла. Каждое считанное слово хранится в std::unordered_map чтобы определить, сколько раз это слово встречается в файле.
MexFunction конструктор выполняет следующие шаги:
Звонить mexLock для предотвращения сброса функции MEX из памяти.
Получите полный путь к текстовому файлу из MATLAB с помощью matlab:: engine:: MATLABEngine:: eval и matlab:: engine:: MATLABEngine:: getVariable.
Откройте текстовый файл в std::ifstream входной поток.
Деструктор класса закрывает файл.
Каждый вызов функции MEX считывает слово из текстового файла и добавляет его к неупорядоченной карте или просто увеличивает число слов для этого слова, если оно существует на карте. Функция MEX отображает текущее слово и его количество в окне команды MATLAB с помощью std::ostringstream выходной поток. Чтобы разблокировать функцию MEX, передайте аргумент (например, 'unlock') функции.
displayOnMATLAB функция-член использует matlab:: engine:: MATLABEngine:: feval для вызова MATLABfprintf со строкой, записанной в выходной поток.
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <unordered_map>
#include <fstream>
using matlab::mex::ArgumentList;
using namespace matlab::data;
class MexFunction : public matlab::mex::Function {
// Input stream to read words from file
std::ifstream inFile;
// Unordered map to keep track of word count
std::unordered_map<std::string, int> wordCount;
// Pointer to MATLAB engine
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
// Factory to create MATLAB data arrays
ArrayFactory factory;
public:
MexFunction() {
mexLock();
matlabPtr->eval(u"fname = fullfile(matlabroot, 'examples', 'matlab', 'sonnets.txt');");
matlab::data::CharArray fileName = matlabPtr->getVariable(u"fname");
inFile.open(fileName.toAscii());
if (!inFile.is_open()) {
std::ostringstream stream;
stream << "Failed to open sonnets.txt" << std::endl;
displayOnMATLAB(stream);
}
}
~MexFunction() {
if (inFile.is_open())
inFile.close();
}
void operator()(ArgumentList outputs, ArgumentList inputs) {
if (inFile.is_open() && !inFile.eof()) {
std::string word;
inFile >> word;
wordCount[word]++;
std::ostringstream stream;
stream << "Read : " << "\"" << word << "\""
<< ", current count: " << wordCount[word] << std::endl;
displayOnMATLAB(stream);
}
if (!inputs.empty() || !inFile.is_open()) {
mexUnlock();
}
}
void displayOnMATLAB(const std::ostringstream& stream){
matlabPtr->feval(u"fprintf", 0,
std::vector<Array>({ factory.createScalar(stream.str()) }));
}
};Откройте файл исходного кода, sonnetWordCount.cpp, в редакторе и использовать mex для компиляции функции MEX.
mex sonnetWordCount.cpp
Многократный вызов функции MEX для подсчета использования слов.
>> sonnetWordCount Read : "THE", current count: 1 >> sonnetWordCount Read : "SONNETS", current count: 1 >> sonnetWordCount Read : "by", current count: 1 >> sonnetWordCount Read : "William", current count: 1 >> sonnetWordCount Read : "Shakespeare", current count: 1 >> sonnetWordCount('unlock')