Печать в командное окно MATLAB из mex-файла и другого потока

#c #multithreading #matlab #printf #mex

#c #многопоточность #matlab #printf #mex

Вопрос:

Я изменил пример программы, чтобы продемонстрировать проблему: она печатает строку каждую секунду. Проблема в том, что сообщения появляются в окне командной строки после того, как MATLAB возвращается в состояние ожидания (все сразу). Если он вызывается из командной строки и MATLAB возвращается в режим ожидания, сообщения появляются в окне командной строки:

 mexFile;
 

Но в этом случае:

 mexFile; while 1; end;
 

Сообщения появляются после того, как я прерываю бесконечный цикл с помощью ^C.

Вот мой исходный код. Он использует feval("fprintf"...) . Последующий вызов pause(0.001) or drawnow ничего не меняет.

Как я могу заставить matlab «сбрасывать» сообщения в командное окно?

 #include "mex.hpp"
#include "mexAdapter.hpp"
#include <thread>
#include <future>    


class MexFunction : public matlab::mex::Function {
private:
    std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
public:
    void print(const std::stringamp; msg)
    {
        matlab::data::ArrayFactory factory;
        // Pass stream content to MATLAB fprintf function
        matlabPtr->fevalAsync(u"fprintf", 0,
            std::vector<matlab::data::Array>({ factory.createScalar(msg) }));
        // matlabPtr->evalAsync(u"pause(0.001);");
    }

    void DisplayDateTime() {
        matlab::data::ArrayFactory factory;
        for (int count = 0; count < 20; count  )
        {
            print("Loop "   std::to_string(count)   "n");
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }

    void operator()(matlab::mex::ArgumentList outputs,
        matlab::mex::ArgumentList inputs) {
        mexLock();
        voidStdFuture = std::async(std::launch::async,
            amp;MexFunction::DisplayDateTime, this);
    }
};
 

Комментарии:

1. Мне кажется, это указывает на то, что асинхронный вызов должен выполняться после завершения работы MEX-файла. Вы запускаете свой MEX-файл вне процесса? В противном случае процесс MATLAB зависает до завершения работы MEX-файла. Может быть, вызов drawnow после печати помогает?

2. Вы пробовали feval ? Не уверен, но из того, что вы пишете в другом вопросе, кажется, что по сравнению со старым C API многое изменилось.

3. @CrisLuengo Если вы вызовете feval из отдельного потока, matlab выйдет из строя. Если вы вызываете feval из основного потока, сообщения появляются, даже если matlab занят. И нет, drawnow ничего не меняет.

4. fevalAsync может записывать в предоставленный пользователем буфер потока . Итак, похоже, что вам нужно определить подкласс std::basic_streambuf , который обертывает буфер потока std::wcout . MATALAB нуждается в буфере потока типа basic_streambuf<char16_t> , в то время wcout как имеет буфер потока типа basic_streambuf<wchar_t> . Это следует учитывать при переопределении виртуальных методов. Эти методы правильно вызывают методы буфера обернутого потока.