[/
    Copyright 2014 Renato Tegon Forti, Antony Polukhin
    Copyright Antony Polukhin, 2015-2025
    Distributed under the Boost Software License, Version 1.0.
    (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]

[section F.A.Q.]

* [*Question:]  Is Boost.DLL thread-safe?
  * [*Answer:]  Some platforms allow concurrent calls to `dlopen` like functions.
For those platforms Boost.DLL is safe in the manner as all the C++ Standard Library containers are: it is
safe to use different instances of shared_library from different threads even if all the instances loaded the same library. On other platforms it
is not safe to concurrently call any of the functions from Boost.DLL (even a `shared_library::location()` call triggers a race condition).
See [link boost_dll.limitations.multithread Limitations, Thread safe library loading].

[pre
]

* [*Question:]  Why on Linux symbols from one plugin are seen in another? Can't get symbol with same name from right plugin!
  * [*Answer:]  You've run into the symbol shadowing problem. Compile your plugins with "-fvisibility=hidden"
flag and take a look to the Tutorial section.

[pre
]

* [*Question:]  How Unicode (Windows) is handled?
  * [*Answer:]  Boost.DLL supports Unicode, so that you could provide Unicode paths to it.

[pre
]

* [*Question:]  Can I open an executable file?
  * [*Answer:]  Yes, you can. Symbols need be exported using in the executable using `BOOST_SYMBOL_EXPORT`
or `BOOST_DLL_ALIAS`. You can call `shared_library(program_location())` to load yourself. Refer to
the Tutorial section for more info. You can also query executables, just provide a path to the executable
to `library_info` class.

[pre
]

* [*Question:]  What if I specify wrong type in `shared_library::get<T>` or `import<T>`?
  * [*Answer:]  Usually you'll end up with `Segmentation Fault`. However it is safe to make types
more strict, for example making `const int` from an `int` will not harm.

[pre
]

* [*Question:]  Does your library guarantee ABI stability of methods?
  * [*Answer:]  Library only guarantees that alias names created using the `BOOST_DLL_ALIAS` macros
will not change with the change of compiler or platform. You must take care of functions ABI and API
stability by your own.

[pre
]

* [*Question:]  Are there any function signature restrictions for the exported/imported functions?
  * [*Answer:]  No. You may import/export functions with any signature and any return parameter.

[pre
]

* [*Question:]  I have 2 plugins that use same shared library. Would be the shared library loaded twice?
  * [*Answer:]  No. Pugins will share the shared library instance.

[pre
]

* [*Question:]  I have 2 plugins each of them must work with it's own version of `libsome_library` shared library. How to achieve that?
  * [*Answer:]  Avoid such situations by statically linking in the libsome_library into each plugin and loading plugins with `load_mode::rtld_deepbind`.

[pre
]

* [*Question:]  Is there a `RTLD_NODELETE` mode? Is there a built in way to skip unload or "leak" a dynamically loaded library?
  * [*Answer:]  No. Boost tries to support best practices and leaking resources is not one of them. If you are dynamically loading a third party library that fails to unload, try the following:
```
std::vector<boost::dll::shared_library>& late_unload_registry() {
    static std::vector<boost::dll::shared_library> registry;
    return registry;
}
```
and push the library to that registry `late_unload_registry().emplace_back(third_party_shared_library)`. It will force the library to not unload till the end of program.

If the above `late_unload_registry()` does not help - ask the vendor of the library for support to dynamically load/unload the library.

[pre
]

* [*Question:]  How to load a shared object from memory??
  * [*Answer:]  All existing OS avoid loading shared libraries directly from userspace memory, so you'll find no syscall for such case. Currently Boost.DLL provides no means for honest loading shared objects from memory. This requires reimplementing dynamic linker logic in userspace for all the platforms, which is a huge amount of work and very error-prone. However working patches are welcomed!

Workaround would be to write plugin into a temporary file in RAM and load plugin from it:
```
#include <boost/filesystem.hpp>
#include <boost/dll.hpp>
using namespace boost;

dll:shared_library load_from_memory(unsigned char* data, std::size_t size, const filesystem::path& tmp_plugin_path = filesystem::unique_path() / "libplugin.so") {
    const filesystem::path plugin_location = filesystem::temp_directory_path() / tmp_plugin_path;
    filesystem::create_directories(plugin_location.parent_path());
    filesystem::ofstream ofs(plugin_location, std::ios::out|std::ios::bin|std::ios::trunc);
    ofs.write(data, size);

    return dll::shared_library(plugin_location);
}
```

But there's no guarantee that `filesystem::temp_directory_path()` will actually write to RAM, that's very platform dependent.

[pre
]

* [*Question:] Can I use function pointer type (like `void(*)()`) instead of function type (like `void()`) to import function?
  * [*Answer:] No you can't because the meaning of importing a function pointer is different:
    * `lib.get<void()>("func")` imports a function `void func()`
    * `lib.get<void(*)()>("func_var")` imports a variable that stores a pointer to the function `auto func_var = &func`

[pre
]
  
* [*Question:]  I have found a bug, how do I notify?
  * [*Answer:]  Create an [@https://github.com/apolukhin/Boost.DLL/issues issue at GitHub] with a detailed description.

[endsect]



