Browse Source

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>
wdskuki 1 day ago
parent
commit
984c0eefcc
1 changed files with 36 additions and 1 deletions
  1. 36 1
      src/interpreter/dll.c

+ 36 - 1
src/interpreter/dll.c

@@ -10,6 +10,8 @@
 
 
 #else
 #else
 #include <dlfcn.h>
 #include <dlfcn.h>
+#include <stdlib.h>
+#include <string.h>
 #endif
 #endif
 
 
 typedef bool (*py_module_initialize_t)() PY_RAISE PY_RETURN;
 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;
     if(dll == NULL) return 0;
     py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, f_init_name);
     py_module_initialize_t f_init = (py_module_initialize_t)GetProcAddress(dll, f_init_name);
 #else
 #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;
     if(dll == NULL) return 0;
     py_module_initialize_t f_init = (py_module_initialize_t)dlsym(dll, f_init_name);
     py_module_initialize_t f_init = (py_module_initialize_t)dlsym(dll, f_init_name);
 #endif
 #endif