Управление внешние ресурсы от MEX-функций

MEX-функции, которые соединяются с внешними ресурсами как сокеты, датчики, файлы и базы данных, должны управлять этими ресурсами. Поскольку вы реализуете MEX-функции C++ как классы, можно задать конструктора и функции деструктора, чтобы управлять этими ресурсами и переменными, которые сохраняются через повторные вызовы MEX-функции.

Когда вы вызываете MEX-функцию, MATLAB® создает экземпляр класса MexFunction. Этот объект сохраняется для сеанса работы с MATLAB или пока вы не очищаете объект с командой mex clear. Повторные вызовы MEX-функции могут обработать входящие данные и высвободить средства по окончании.

Чтение текстового файла

Эта MEX-функция открывает текстовый файл и читает одно слово каждый раз, когда вы вызываете функцию. Класс MexFunction, который реализует MEX-функцию, задает конструктора и деструктор, чтобы открыть и закрыть файл. Каждое чтение слова сохранено в std::unordered_map, чтобы определить число раз, что слово происходит в файле.

Конструктор

Конструктор MexFunction выполняет эти шаги:

Деструктор

Деструктор класса закрывает файл.

Оператор Оператора вызова функции ()

Каждый вызов MEX-функции читает слово из текстового файла и добавляет его к незаказанной карте, или просто постепенно увеличивает подсчет слов для того слова, если это уже существует в карте. MEX-функция отображает текущее слово и его количество в окне команды MATLAB с помощью потока вывода std::ostringstream. Чтобы разблокировать MEX-функцию, передайте аргумент (такой как 'unlock') к функции.

Отобразитесь на MATLAB

Функция членства displayOnMATLAB использует MATLAB:: механизм:: MATLABEngine:: feval, чтобы вызвать fprintf MATLAB функционируют со строкой, записанной в поток вывода.

Листинг кода

#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

Откройте файл исходного кода, 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')

Смотрите также

Похожие темы

Была ли эта тема полезной?