import ctypes as C # Загружаем необязательный настольный модуль через стабильный C ABI. from functools import lru_cache # Удерживаем DLL и её функции, пока расчётные задачи используют указатели. import os # Разрешаем явно выбрать альтернативную библиотеку в тестах или нестандартной установке. from pathlib import Path # Ищем модуль рядом с уже выбранной основной SETProtocol DLL. import sys # Расширение нативного модуля соответствует текущей настольной ОС. @lru_cache(maxsize=1) # Один экземпляр DLL безопасно обслуживает независимые расчёты без глобальных рабочих буферов. def library(core_path): # Путь основной библиотеки задаёт согласованный каталог установки обоих модулей. name = {"win32": "setsignal_eigen.dll", "darwin": "libsetsignal_eigen.dylib"}.get(sys.platform, "libsetsignal_eigen.so") # Отдельное имя сохраняет возможность запуска с прежней основной DLL. path = Path(os.environ.get("SETSIGNAL_EIGEN_LIBRARY", str(Path(core_path).resolve().with_name(name)))) # Явный путь окружения имеет приоритет над соседним компонентом приложения. try: # Отсутствующий или несовместимый компонент показывается пользователю как ошибка выбранного варианта. result = C.CDLL(str(path)) # Загружаем только явно вычисленный путь, не подбирая случайную DLL из PATH. pointer = C.POINTER(C.c_double) # Входные и выходные массивы содержат значения double общего алгоритма. result.set_signal_reconstruct_eigen.argtypes = [pointer, pointer, C.c_size_t, C.c_int, C.c_uint, C.c_size_t, C.c_int, pointer, pointer, pointer, pointer, C.c_size_t] # Сигнатура повторяет исходную реконструкцию и сохраняет размер size_t для x86/x64. result.set_signal_reconstruct_eigen.restype = C.c_int # Ошибки ранга и нехватки памяти возвращаются целочисленным кодом. return result # Удерживаем объект DLL для всего времени жизни привязанной функции. except (AttributeError, OSError) as error: # Отдельно обрабатываем отсутствие экспорта и невозможность загрузки библиотеки. raise ValueError("Eigen QR недоступен: соберите модуль cpp/signal-eigen/build.py для разрядности приложения") from error # Не подменяем явно выбранный Eigen текущим МНК.