Fix C extension module import on Linux (#472)

* Fix C extension module import on Linux

* minor fix

---------

Co-authored-by: wdsmini <wdsmini@wdsmini.local>
Co-authored-by: blueloveTH <blueloveTH@foxmail.com>
This commit is contained in:
wdskuki 2026-03-18 14:55:38 +08:00 committed by GitHub
parent cf70668a2f
commit 984c0eefcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -10,6 +10,8 @@
#else
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#endif
typedef bool (*py_module_initialize_t)() PY_RAISE PY_RETURN;
@ -21,7 +23,40 @@ int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN {
if(dll == NULL) return 0;
py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, f_init_name);
#else
void* dll = dlopen(path, RTLD_LAZY);
void* dll = NULL;
// On Linux, dlopen doesn't automatically add .so suffix like Windows does with .dll
// Also, CMake typically generates libXxx.so instead of Xxx.so
// Try: path.so, libpath.so, then the original path
char* path_with_so = NULL;
char* path_with_lib = NULL;
size_t path_len = strlen(path);
// Try path.so
path_with_so = py_malloc(path_len + 4); // .so + null terminator
if(path_with_so != NULL) {
strcpy(path_with_so, path);
strcat(path_with_so, ".so");
dll = dlopen(path_with_so, RTLD_LAZY);
py_free(path_with_so);
}
// Try libpath.so if path.so didn't work
if(dll == NULL) {
path_with_lib = py_malloc(path_len + 7); // lib + .so + null terminator
if(path_with_lib != NULL) {
strcpy(path_with_lib, "lib");
strcat(path_with_lib, path);
strcat(path_with_lib, ".so");
dll = dlopen(path_with_lib, RTLD_LAZY);
py_free(path_with_lib);
}
}
// Fallback to original path
if(dll == NULL) {
dll = dlopen(path, RTLD_LAZY);
}
if(dll == NULL) return 0;
py_module_initialize_t f_init = (py_module_initialize_t)dlsym(dll, f_init_name);
#endif