/* Copyright 2017 The MathWorks, Inc. */ #ifndef CPPSHAREDLIB_FACTORY_IMPL_HPP #define CPPSHAREDLIB_FACTORY_IMPL_HPP #include "../cppsharedlib_factory.hpp" #include "../cppsharedlib_exception.hpp" #include "cppsharedlib_ctf_path.hpp" namespace { std::once_flag sessionFlag; static std::atomic initialized(false); static std::atomic terminated(false); bool init(const std::vector& options) { try{ std::vector options_v(options.size()); std::transform(options.begin(), options.end(), options_v.begin(), [](const std::u16string& option){ return const_cast(option.c_str()); }); runtime_create_session(options_v.data(), options_v.size()); } catch (...) { // not much we can do here. } return true; } void initIt(const std::vector& options) { initialized = init(options); } void initSession(const std::vector& options) { if (terminated) { throw matlab::cpplib::CppSharedLibException("MATLABApplication is already terminated and cannot be reinitialized."); } if (initialized) { throw matlab::cpplib::CppSharedLibException("MATLABApplication is already initialized."); } std::call_once(sessionFlag, initIt, options); } std::function* userMainFcnPtr; extern "C" inline int wrapUserMain(int argc, const char** argv) { return (*userMainFcnPtr)(argc, argv); } } namespace matlab { namespace cpplib { inline std::shared_ptr initMATLABApplication(const MATLABApplicationMode mode, const std::vector& options) { if (mode == MATLABApplicationMode::IN_PROCESS) { initSession(options); }else { const std::string STR_OUTPROC = "-outproc"; const std::u16string U16STR_OUTPROC(STR_OUTPROC.cbegin(), STR_OUTPROC.cend()); std::vector newOptions={U16STR_OUTPROC}; std::copy(options.begin(),options.end(), std::back_inserter(newOptions)); initSession(newOptions); } return std::shared_ptr(new MATLABApplication(mode, options)); } inline std::unique_ptr initMATLABLibrary(std::shared_ptr application, const std::u16string& ctffilename) { return initMATLABLibraryAsync(application, ctffilename).get(); } inline FutureResult> initMATLABLibraryAsync(std::shared_ptr application, const std::u16string& ctffilename) { const std::u16string absolutePathToCTF = detail::getPathToCtf(ctffilename); if (absolutePathToCTF.empty()) { std::string str("Unable to open file '"); str += convertUTF16StringToUTF8String(ctffilename); str += "'."; throw CppSharedLibException(str); } // absolutePathToCTF is intentionally passed by copy rather than by reference. auto startMVMType = [&application, absolutePathToCTF]() { bool errFlag = false; uint64_t handle = create_mvm_instance(absolutePathToCTF.c_str(), &errFlag); if (errFlag) { throw CppSharedLibException("Failed to initialize MATLABLibrary."); } return std::unique_ptr(new MATLABLibrary(application, handle)); }; std::future> stdF = std::async(std::launch::async, startMVMType); FutureResult> future(std::move(stdF)); return (future); } inline int runMain(std::function, int, const char**)> mainFcn, std::shared_ptr&& appsession, int argc, const char **argv) { using namespace std::placeholders; std::function userMainFcn = [&](int argc, const char** argv) {return mainFcn(std::move(appsession), argc, argv);}; userMainFcnPtr = &userMainFcn; return cppsharedlib_run_main(wrapUserMain, argc, argv); } } } #endif //CPPSHAREDLIB_FACTORY_IMPL_HPP