| 121 | } |
| 122 | |
| 123 | std::pair<void*, void*> wf::get_new_instance_handle(const std::string& path, bool can_unload_so) |
| 124 | { |
| 125 | if (!check_plugin_api_version(path, can_unload_so)) |
| 126 | { |
| 127 | return {nullptr, nullptr}; |
| 128 | } |
| 129 | |
| 130 | // RTLD_GLOBAL is required for RTTI/dynamic_cast across plugins |
| 131 | void *handle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL); |
| 132 | if (handle == NULL) |
| 133 | { |
| 134 | LOGE("error loading plugin [", path, "]: ", dlerror()); |
| 135 | return {nullptr, nullptr}; |
| 136 | } |
| 137 | |
| 138 | /* Check plugin version */ |
| 139 | auto new_instance_func_ptr = dlsym(handle, "newInstance"); |
| 140 | if (new_instance_func_ptr == NULL) |
| 141 | { |
| 142 | LOGE(path, ": missing newInstance(). ", dlerror()); |
| 143 | dlclose(handle); |
| 144 | return {nullptr, nullptr}; |
| 145 | } |
| 146 | |
| 147 | LOGD("Loaded plugin ", path.c_str()); |
| 148 | |
| 149 | return {handle, new_instance_func_ptr}; |
| 150 | } |
| 151 | |
| 152 | std::optional<wf::loaded_plugin_t> wf::plugin_manager_t::load_plugin_from_file(std::string path) |
| 153 | { |
nothing calls this directly
no test coverage detected