-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support non-extern-C symbols #27
Comments
Current statusHello, Linux and MacOS
dylib lib("lib.so");
auto ver = lib.get_variable<double>("driver::infos::version");
dylib lib("lib.so");
// get_function<T> for T = [module *(const char *)]
auto mod = lib.get_function<module *(const char *)>("driver::factory"); To be able to iterate over variadic template arguments, i temporally replaced the current syntax with the following one : // old syntax
// get_function<T>
auto mod = lib.get_function<module *(const char *)>("driver::factory");
// temporary new syntax
// get_function<Ret, Args...>
auto mod = lib.get_function<module *, const char *>("driver::factory"); Do you know if there is a way to "decompose" a function template argument to get its return value as Windows
|
UpdateLinux and MacOS
dylib lib("lib");
auto ver = lib.get_variable<double>("driver::infos::version");
dylib lib("lib");
auto mod = lib.get_function<module *, const char *>("driver::factory");
auto set_inst = lib.get_function<void, module &&>("driver::instance::set");
auto print = lib.get_function<void, std::ostream &, const std::string &>("driver::tools::print"); Windows
Question
|
Well, But are you sure you're not going about this the wrong way? I mean, take the function's proper type, then apply name mangling (not yourself - there's an ABI library for that), then look for the symbol. |
This is what I'm doing but i'm not sure there is an abi lib to mangle names (i'm currently using There is this abi function to char *demangledName = abi::__cxa_demangle(av[i], NULL, NULL, &status); |
Ah, right, |
Also, this may be relevant for Windows. |
You are right, to do so, i made the following code to have at the end the accurate function symbol mangled name in all situations (except pointers and namespaces) on unix : template <typename T, typename U, typename... Args>
static std::string TemplateMangle()
{
return TemplateMangle<T>() + TemplateMangle<U, Args...>();
}
template <typename T>
static std::string TemplateMangle()
{
std::string t = typeid(T).name();
if (std::is_lvalue_reference<T>::value) {
std::string tmp = "R";
if (std::is_const<typename std::remove_reference<T>::type>::value)
tmp += 'K';
t = tmp + t;
}
else if (std::is_rvalue_reference<T>::value) {
std::string tmp = "O";
if (std::is_const<typename std::remove_reference<T>::type>::value)
tmp += 'K';
t = tmp + t;
}
return t;
}
template<typename ReturnType, typename Arg1, typename ...Args>
static std::string mangle_function(const std::string &name) {
return "_Z" + std::to_string(name.size()) + name + TemplateMangle<Arg1, Args...>();
}
template<typename ReturnType>
static std::string mangle_function(const std::string &name) {
return "_Z" + std::to_string(name.size()) + name + typeid(void).name();
} |
Let me first note I've asked about this at StackOverflow. Now, for your implementation.
|
You're right, but currently I prefer to focus on making the proof of concept work
Yes, i'm using this document to implement the feature
The following code mangles namespaced varibles on unix : class dylib {
private:
static std::vector<std::string> string_to_vector(const std::string &str, const char *delimiters) {
std::vector<std::string> tokens;
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
return tokens;
}
static std::string mangle_variable(const std::string &name) {
if (name.find("::") == std::string::npos)
return name;
auto ns_list = string_to_vector(name, "::");
if (ns_list.size() == 1)
return ns_list.front();
std::string mangled = "_ZN";
for (auto &ns : ns_list)
mangled += std::to_string(ns.size()) + ns;
return mangled + 'E';
}
} |
I think you may be misusing the delimiters parameter... it takes several chars, each of which is a delimited. |
I'm gonna release |
@martin-olivier : There's always version 3.0... |
Here are some outstanding SO questions about doing this: |
Good news - here's MSVC mangling code for you: https://godbolt.org/z/nnW19qzYE Right now, that code requires C++20, but with a little work you can bring that down to C++11 and integrate it into yur own code. |
Hey, did anyone did that "little work"? I kinda need it to build in some old compilers. :/ |
Don't know if this is of any help. When demangling the other way, I always use boost. There is also a nice static type_info that uses a string_view and the PRETTY_FUNCTION macro in order to extract the unmangled names. There a few around and can't remember which I used but here is one of them. Either way I'd probably buy not build and would've thought a compiler/support library builtin must be able to mangle names. Last time I looked at libsupcxx many years ago I think I saw one. Personally though I'd probably rather use the compiler and register something into my library. I appreciate that only works for some usecases though, where you can modify the sources and you're generating something more like a plugin, rather than just very late binding of an arbitrary function. Let the compiler do that work and pull symbols in using something more like a factory with my own key. |
This is a C++ library for working with shared objects, but it only supports unmangled, C-style functions. That means it doesn't serve its primary function. The library must support any C++ function one can load from a shared object. Naturally, this is ABI-specific, but that's either for the user to configure and build accordingly, or potentially a case for multi-ABI support. The latter is much more complicated, and would be a feature request in itself, but function symbols should definitely be looked up by their mangled name, if they're not extern-C.
The text was updated successfully, but these errors were encountered: