31 vm_->log(std::format(
"FFI::{}(\"{}\")\n", __func__, library.string()));
37 HMODULE lib = LoadLibraryA(library.string().c_str());
41 ss <<
"FFI Error: Failed to load library " << library.string() <<
". Code: " << GetLastError();
42 throw std::runtime_error(ss.str());
45 auto entry_point = (PluginEntryFunc)GetProcAddress(lib,
"phasor_plugin_entry");
47 void *lib = dlopen(library.string().c_str(), RTLD_NOW);
51 ss <<
"FFI Error: Failed to load library " << library.string() <<
". Error: " << dlerror();
52 throw std::runtime_error(ss.str());
55 auto entry_point = (PluginEntryFunc)dlsym(lib,
"phasor_plugin_entry");
60 throw std::runtime_error(
61 std::string(
"FFI Error: Could not find entry point 'phasor_plugin_entry' in " + library.string()));
73 entry_point(&api,
reinterpret_cast<PhasorVM *
>(vm));
75 plugins_.push_back(
Plugin{.handle = lib, .path = library.string(), .init = entry_point, .shutdown =
nullptr});
94 vm_->log(std::format(
"FFI::{}(\"{}\")\n", __func__, folder.string()));
100 std::vector<std::string> plugins;
101 std::filesystem::path exeDir;
102 std::vector<std::filesystem::path> foldersToScan;
104 if (folder.is_absolute())
106 foldersToScan.push_back(folder);
112 GetModuleFileNameA(
nullptr, path, MAX_PATH);
113 exeDir = std::filesystem::path(path).parent_path();
114#elif defined(__APPLE__)
116 u32 size =
sizeof(path);
117 if (_NSGetExecutablePath(path, &size) == 0)
118 exeDir = std::filesystem::path(path).parent_path();
120 exeDir = std::filesystem::current_path();
121#elif defined(__linux__)
123 ssize_t count = readlink(
"/proc/self/exe", path,
sizeof(path));
125 exeDir = std::filesystem::path(std::string(path, count)).parent_path();
127 exeDir = std::filesystem::current_path();
129 exeDir = std::filesystem::current_path();
132 foldersToScan.push_back(exeDir / folder);
133 if (!std::filesystem::equivalent(exeDir, std::filesystem::current_path()))
134 foldersToScan.push_back(std::filesystem::current_path() / folder);
137 for (
auto &folderPath : foldersToScan)
139 if (!std::filesystem::exists(folderPath) || !std::filesystem::is_directory(folderPath))
142 for (
auto &p : std::filesystem::directory_iterator(folderPath))
144 if (!p.is_regular_file())
146 auto ext = p.path().extension().string();
148 if (ext ==
".dll" || ext ==
".phsp")
149#elif defined(__APPLE__)
150 if (ext ==
".dylib" || ext ==
".phsp")
152 if (ext ==
".so" || ext ==
".phsp")
154 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.