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]