PengZheng commented on PR #441:
URL: https://github.com/apache/celix/pull/441#issuecomment-1239468298

   > The challenge I see here is the same as with importing/exporting libraries 
from bundles: If there are libraries which are different, but have the same 
SONAME header, a call to dlopen will reuse a (transitive) library with the same 
SONAME instead of loading a new lib. This is even true if DL_LOCAL is used.
   
   It turns out that if we provide the full absolute path to `dlopen`, we may 
workaround the problem.  I check the following example on my Linux machine:
   
   ```CMake
   # CMakeLists.txt
   cmake_minimum_required(VERSION 3.23)
   project(hello_solib C)
   
   set(CMAKE_C_STANDARD 99)
   
   
   add_library(hello_impl1 SHARED hello1.c)
   set_target_properties(hello_impl1 PROPERTIES LIBRARY_OUTPUT_DIRECTORY 
${CMAKE_CURRENT_BINARY_DIR}/impl1)
   set_target_properties(hello_impl1 PROPERTIES OUTPUT_NAME hello)
   add_library(hello_impl2 SHARED hello2.c)
   set_target_properties(hello_impl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY 
${CMAKE_CURRENT_BINARY_DIR}/impl2)
   set_target_properties(hello_impl2 PROPERTIES OUTPUT_NAME hello)
   
   add_executable(hello_solib main.c)
   target_compile_definitions(hello_solib PRIVATE 
HELLO1_LOC="$<TARGET_FILE:hello_impl1>")
   target_compile_definitions(hello_solib PRIVATE 
HELLO2_LOC="$<TARGET_FILE:hello_impl2>")
   target_link_libraries(hello_solib PRIVATE dl)
   
   ```
   
   ```C
   //main.c
   #include "hello.h"
   #include <assert.h>
   #include <dlfcn.h>
   #include <stdio.h>
   
   int main() {
       int (*funcp1)(void);
       int (*funcp2)(void);
       void *handle1;
       void *handle2;
       printf("impl1=%s\n", HELLO1_LOC);
       handle1 = dlopen(HELLO1_LOC, RTLD_LAZY);
       assert(handle1 != NULL);
       printf("impl2=%s\n", HELLO2_LOC);
       handle2 = dlopen(HELLO2_LOC, RTLD_LAZY);
       assert(handle2 != NULL);
       *(void **)(&funcp2) = dlsym(handle2, "hello");
       funcp2();
       *(void **)(&funcp1) = dlsym(handle1, "hello");
       funcp1();
       dlclose(handle2);
       dlclose(handle1);
       return 0;
   }
   ```
   
   ```C
   //hello.h
   #ifndef HELLO_SOLIB_HELLO_H
   #define HELLO_SOLIB_HELLO_H
   #ifdef __cplusplus
   extern "C" {
   #endif
   
   int hello(void);
   
   #ifdef __cplusplus
   }
   #endif
   #endif //HELLO_SOLIB_HELLO_H
   
   ```
   
   ```C
   //hello1.c
   #include "hello.h"
   #include <stdio.h>
   
   int hello(void) {
       printf("hello1\n");
   }
   ```
   
   ```C
   //hello2.c
   #include "hello.h"
   #include <stdio.h>
   
   int hello(void) {
       printf("hello2\n");
   }
   ```
   
   Running the binary produces the following console output:
   
   ```
   /home/peng/Downloads/hello_solib/cmake-build-debug/hello_solib
   impl1=/home/peng/Downloads/hello_solib/cmake-build-debug/impl1/libhello.so
   impl2=/home/peng/Downloads/hello_solib/cmake-build-debug/impl2/libhello.so
   hello2
   hello1
   
   Process finished with exit code 0
   ```
   
   I don't use Mac, and thus can not check for MacOS.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to