Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 3 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, write to the Free Software 18 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 19 : * USA. 20 : */ 21 : #pragma once 22 : 23 : #include "jamiplugin.h" 24 : #include <dlfcn.h> 25 : #include <string> 26 : #include <memory> 27 : 28 : namespace jami { 29 : 30 : /** 31 : * @class Plugin 32 : * @brief This class is used to attempt loading a plugin library. 33 : */ 34 : class Plugin 35 : { 36 : public: 37 8 : virtual ~Plugin() = default; 38 : 39 : /** 40 : * @brief Load plugin's library. 41 : * @return DLPlugin if success. 42 : */ 43 : static Plugin* load(const std::string& path, std::string& error); 44 : virtual void* getSymbol(const char* name) const = 0; 45 : 46 : /** 47 : * @brief Search loaded library for its initialization function 48 : * @return Plugin's initialization function. 49 : */ 50 16 : virtual JAMI_PluginInitFunc getInitFunction() const 51 : { 52 16 : return reinterpret_cast<JAMI_PluginInitFunc>(getSymbol(JAMI_DYN_INIT_FUNC_NAME)); 53 : } 54 : 55 : protected: 56 8 : Plugin() = default; 57 : }; 58 : 59 : /** 60 : * @class DLPlugin 61 : * @brief This class is used after a plugin library is successfully loaded. 62 : */ 63 : class DLPlugin : public Plugin 64 : { 65 : public: 66 8 : DLPlugin(void* handle, const std::string& path) 67 24 : : handle_(handle, ::dlclose) 68 8 : , path_ {path} 69 : { 70 8 : api_.context = this; 71 8 : } 72 : 73 16 : virtual ~DLPlugin() { unload(); } 74 : 75 : /** 76 : * @brief Unload plugin's library. 77 : * @return True if success. 78 : */ 79 8 : bool unload() 80 : { 81 8 : if (!handle_) { 82 0 : return false; 83 : } 84 8 : return !(::dlclose(handle_.release())); 85 : } 86 : 87 : /** 88 : * @brief Searchs for symbol in library. 89 : * @param name 90 : * @return symbol. 91 : */ 92 16 : void* getSymbol(const char* name) const 93 : { 94 16 : if (!handle_) 95 0 : return nullptr; 96 : 97 16 : return ::dlsym(handle_.get(), name); 98 : } 99 : 100 40 : const std::string& getPath() const { return path_; } 101 : 102 : public: 103 : void* apiContext_; 104 : JAMI_PluginAPI api_; 105 : 106 : private: 107 : // Pointer to the loaded library returned by dlopen 108 : std::unique_ptr<void, int (*)(void*)> handle_; 109 : // Plugin's data path 110 : const std::string path_; 111 : }; 112 : 113 : } // namespace jami