30 vm_->log(std::format(
"FFI::{}(\"{}\")\n", __func__, library.string()));
36 HMODULE lib = LoadLibraryA(library.string().c_str());
40 ss <<
"FFI Error: Failed to load library " << library.string() <<
". Code: " << GetLastError();
41 throw std::runtime_error(ss.str());
44 auto entry_point = (PluginEntryFunc)GetProcAddress(lib,
"phasor_plugin_entry");
46 void *lib = dlopen(library.string().c_str(), RTLD_NOW);
50 ss <<
"FFI Error: Failed to load library " << library.string() <<
". Error: " << dlerror();
51 throw std::runtime_error(ss.str());
54 auto entry_point = (PluginEntryFunc)dlsym(lib,
"phasor_plugin_entry");
59 throw std::runtime_error(
60 std::string(
"FFI Error: Could not find entry point 'phasor_plugin_entry' in " + library.string()));
72 entry_point(&api,
reinterpret_cast<PhasorVM *
>(vm));
74 plugins_.push_back(
Plugin{.handle = lib, .path = library.string(), .init = entry_point, .shutdown =
nullptr});
93 vm_->log(std::format(
"FFI::{}(\"{}\")\n", __func__, folder.string()));
99 std::vector<std::string> plugins;
100 std::filesystem::path exeDir;
101 std::vector<std::filesystem::path> foldersToScan;
103 if (folder.is_absolute())
105 foldersToScan.push_back(folder);
111 GetModuleFileNameA(
nullptr, path, MAX_PATH);
112 exeDir = std::filesystem::path(path).parent_path();
113#elif defined(__APPLE__)
115 uint32_t size =
sizeof(path);
116 if (_NSGetExecutablePath(path, &size) == 0)
117 exeDir = std::filesystem::path(path).parent_path();
119 exeDir = std::filesystem::current_path();
120#elif defined(__linux__)
122 ssize_t count = readlink(
"/proc/self/exe", path,
sizeof(path));
124 exeDir = std::filesystem::path(std::string(path, count)).parent_path();
126 exeDir = std::filesystem::current_path();
128 exeDir = std::filesystem::current_path();
131 foldersToScan.push_back(exeDir / folder);
132 if (!std::filesystem::equivalent(exeDir, std::filesystem::current_path()))
133 foldersToScan.push_back(std::filesystem::current_path() / folder);
136 for (
auto &folderPath : foldersToScan)
138 if (!std::filesystem::exists(folderPath) || !std::filesystem::is_directory(folderPath))
141 for (
auto &p : std::filesystem::directory_iterator(folderPath))
143 if (!p.is_regular_file())
145 auto ext = p.path().extension().string();
147 if (ext ==
".dll" || ext ==
".phsp")
148#elif defined(__APPLE__)
149 if (ext ==
".dylib" || ext ==
".phsp")
151 if (ext ==
".so" || ext ==
".phsp")
153 plugins.push_back(p.path().string());
void register_native_c_func(PhasorVM *vm, const char *name, PhasorNativeFunction func)
The concrete implementation of the PhasorRegisterFunction API call.