Closed KOLANICH closed 1 year ago
can you make a proper example? because i'm not exactly following you
Currently
namespace HydrArgs::Backend{
extern "C" {
HYDRARGS_BACKEND_API IArgsParser * argsParserFactory(const std::string &name, const std::string &descr, const std::string &usage [[maybe_unused]], std::vector<Arg*> dashedSpec, std::vector<Arg*> positionalSpec, Streams streams = DEFAULT_STREAMS); ///< A factory to create a backend. Can be overridden. Must be exported by a backend shared lib.
using ArgsParserFactoryT = decltype(argsParserFactory);
};
....
const char ctorFuncName[] = "argsParserFactory";
void loadBackend(DiscoveredBackend &backend){
loadedLib = new DynLibT(backend.backendPath);
chosenFactory = loadedLib->get_function<ArgsParserFactoryT>(ctorFuncName);
}
extern C
discards the info about types. It is not good: we can accidentially load a library where this function has different signature and get UB. Of course we can try to check a symbol for API version updated explicitly first, but it is a more weak solution. Loading by a mangled name solves this problem, but mangled names are unfortunately not standardized and not portable over compilers.
The solution for functions would be to have templates to generate mangled names for the most of major conventions used.
HYDRARGS_BACKEND_API IArgsParser * argsParserFactory(const std::string &name, const std::string &descr, const std::string &usage [[maybe_unused]], std::vector<Arg*> dashedSpec, std::vector<Arg*> positionalSpec, Streams streams = DEFAULT_STREAMS); ///< A factory to create a backend. Can be overridden. Must be exported by a backend shared lib.
void loadBackend(DiscoveredBackend &backend){
loadedLib = new DynLibT(backend.backendPath);
chosenFactory = loadedLib->get_function<ArgsParserFactoryT>(ctmn::gen_mangled<ctmn::current_compiler /* a enum */, ArgsParserFactoryT, "argsParserFactory">::name);
}
Then also some template to gen something that can be iterated with all the variants of mangled names (but using the name generated by the current compiler first) for all the compilers, so we can try each variant.
But this example is more about mangling, not demangling.
I think it's not the goal of this library. @wargio probably we should close it
... should be a nice feature to have.
For example, it can be used to link dlls exporting functions in runtime no matter which compiler has created them without discarding their signatures and while keeping code readable.