MEX-функции, которые соединяются с внешними ресурсами как сокеты, датчики, файлы и базы данных, должны управлять этими ресурсами. Поскольку вы реализуете MEX-функции C++ как классы, можно задать конструктора и функции деструктора, чтобы управлять этими ресурсами и переменными, которые сохраняются через повторные вызовы MEX-функции.
Когда вы вызываете MEX-функцию, MATLAB® создает экземпляр MexFunction
класс. Этот объект сохраняется для сеанса работы с MATLAB или пока вы не очищаете объект с clear
mex
команда. Повторные вызовы MEX-функции могут обработать входящие данные и высвободить средства по окончании.
Эта MEX-функция открывает текстовый файл и читает одно слово каждый раз, когда вы вызываете функцию. MexFunction
класс, который реализует MEX-функцию, задает конструктора и деструктор, чтобы открыть и закрыть файл. Каждое чтение слова хранится в std::unordered_map
определить число раз, что слово происходит в файле.
MexFunction
конструктор выполняет эти шаги:
Вызовите mexLock
предотвратить очистку MEX-функции из памяти.
Получите полный путь к текстовому файлу из MATLAB с помощью MATLAB:: механизм:: MATLABEngine:: и MATLAB:: механизм:: MATLABEngine:: getVariable.
Откройте текстовый файл для std::ifstream
введите поток.
Деструктор класса закрывает файл.
Каждый вызов MEX-функции читает слово из текстового файла и добавляет его в неупорядоченную карту, или только постепенно увеличивает подсчет слов для того слова, если это существует в карте. MEX-функция отображает текущее слово и его количество в окне команды MATLAB с помощью std::ostringstream
поток вывода. Чтобы разблокировать MEX-функцию, передайте аргумент (такой как 'unlock'
) к функции.
displayOnMATLAB
функция членства использует MATLAB:: механизм:: MATLABEngine::, чтобы вызвать MATLAB fprintf
функция со строкой, записанной в поток вывода.
#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')