2

I want to create a dll which keeps an instance of the MATLAB engine open for use by other scripts. That is, the goal is to not have to keep initialising and closing the MATLAB instance, which takes time.

For some background, I have a working C++ program which initialises a MATLAB engine and contains a load of functions to do various things in MATLAB. As some kind of minimum example, I have the three scripts below.

header.h

#pragma once
#include "MatlabEngine.hpp"
#include "MatlabDataArray.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <tuple>
#pragma comment (lib,"libmat.lib")
#pragma comment (lib,"libmx.lib")
#pragma comment (lib,"libmex.lib")
#pragma comment (lib,"libeng.lib")

// Example function definition
void setWorkingDir(std::unique_ptr<matlab::engine::MATLABEngine>& matlabPtr, std::string dir);

MatlabFunctions.cpp

#include "header.h"

// Example function
void setWorkingDir(std::unique_ptr<matlab::engine::MATLABEngine>& matlabPtr, std::string dir){
   std::u16string matlabCommand = matlab::engine::convertUTF8StringToUTF16String("cd '"+dir+"'");
   matlabPtr->eval(matlabCommand);
}

Main.cpp

#include "header.h"

int main(){
  using namespace matlab::engine;
  matlab::data::ArrayFactory factory; // Create MATLAB data array factory
  std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB(); // Start MATLAB engine
  
  // Do various functions
}

My goal is to get rid of Main.cpp and create a dll which keeps keeps the MATLAB engine open, allowing the functions in MatlabFunctions.cpp to be run without having to start the MATLAB engine each time.

Is this possible? And if so, how can it be done?

James
  • 99
  • 6
  • dll is still tied to a specific process. you'll need to have the different processes communicate to share a resource- the matlab engine instance. look at methods for inter-process communication (IPC) – Abel Aug 04 '21 at 13:59
  • What do you mean by "for use by other _scripts_"? C++ is not a scripting language. – heap underrun Aug 04 '21 at 14:00
  • On Windows you might want to use the COM interface: https://www.mathworks.com/help/matlab/call-matlab-com-automation-server.html -- but note that you are exchanging the time it takes to start the MATLAB interpreter with that to move data across processes. – Cris Luengo Aug 04 '21 at 14:38

1 Answers1

3

Some people suggested to use IPC here for the task to be done. Using something like COM is not cross-platform and, well, pretty outdated at the moment. As a modern and cross-platform solution, I'd use an actual server application (which will start MATLAB engine and wait for requests) with, for example, gRPC running. Here's tutorial, pretty good one.

Other than that, you can specify your own networking protocol to run your tasks on the server application without the need of IPC, but the gRPC solution works simply out of the box, no bloat coding included.

Leontyev Georgiy
  • 1,295
  • 11
  • 24
  • Thanks for suggestion and link, I'll look into it and accept your answer if it solves the question. – James Aug 04 '21 at 20:29
  • The best solution I found was to create a class which opened an instance of the matlab engine. The engine can then be accessed via functions in the class and remains open. This seems to be the most simple way to keep the matlab engine open as part of a .dll. Thanks for the IPC and gRPC suggestions. – James Aug 23 '21 at 12:44