Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2018-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "PlumedHandle.h" 23 : #include "core/PlumedMain.h" 24 : #include "Tools.h" 25 : #include "lepton/Exception.h" 26 : #include <cstring> 27 : #ifdef __PLUMED_HAS_DLOPEN 28 : #include <dlfcn.h> 29 : #endif 30 : 31 : // Including Plumed.h in this manner allows to create a local 32 : // implementation of the wrapper in an anonymous namespace. 33 : // This allows to avoid recoding all the Plumed.h stuff here 34 : // and at the same time avoids possible conflicts. 35 : #define __PLUMED_WRAPPER_IMPLEMENTATION 1 36 : #define __PLUMED_WRAPPER_EXTERN 0 37 : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 1 38 : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 1 39 : #include "../wrapper/Plumed.h" 40 : 41 : namespace PLMD { 42 : 43 : 44 11 : PlumedHandle::PlumedHandle(): 45 11 : local(Tools::make_unique<PlumedMain>()) { 46 11 : } 47 : 48 1 : PlumedHandle::PlumedHandle(const char* kernel) 49 : #ifdef __PLUMED_HAS_DLOPEN 50 : : 51 1 : loaded(plumed_c2v(plumed_create_dlopen(kernel))) { 52 : if(!plumed_valid(plumed_v2c(loaded))) { 53 : // this is necessary to make sure loaded is properly destroyed 54 0 : plumed_finalize(plumed_v2c(loaded)); 55 0 : plumed_error() << "You are trying to dynamically load a kernel, but the path " << kernel <<" could not be opened"; 56 : } 57 1 : } 58 : #else 59 : { 60 : plumed_error() << "You are trying to dynamically load a kernel, but PLUMED was compiled without dlopen"; 61 : } 62 : #endif 63 : 64 12 : PlumedHandle::~PlumedHandle() { 65 12 : if(loaded) { 66 1 : plumed_finalize(plumed_v2c(loaded)); 67 : } 68 12 : } 69 : 70 1 : PlumedHandle PlumedHandle::dlopen(const char* path) { 71 1 : return PlumedHandle(path); 72 : } 73 : 74 1476 : void PlumedHandle::cmd(const std::string & key,const TypesafePtr & ptr) { 75 1476 : if(local) { 76 2508 : local->cmd(key.c_str(),ptr); 77 222 : } else if(loaded) { 78 : plumed_safeptr safe; 79 222 : safe.ptr=ptr.getRaw(); 80 222 : safe.nelem=ptr.getNelem(); 81 222 : safe.shape=const_cast<std::size_t*>(ptr.getShape()); 82 222 : safe.flags=ptr.getFlags(); 83 222 : safe.opt=nullptr; 84 222 : plumed_cmd(plumed_v2c(loaded),key.c_str(),safe); 85 : } else { 86 0 : plumed_error() << "should never arrive here (either one or the other should work)"; 87 : } 88 1476 : } 89 : 90 0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept: 91 : local(std::move(other.local)), 92 0 : loaded(other.loaded) { 93 0 : other.loaded=nullptr; 94 0 : } 95 : 96 0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept { 97 0 : if(this!=&other) { 98 0 : if(loaded) { 99 0 : plumed_finalize(plumed_v2c(loaded)); 100 : } 101 : local=std::move(other.local); 102 0 : loaded=other.loaded; 103 0 : other.loaded=nullptr; 104 : } 105 0 : return *this; 106 : } 107 : 108 : }