Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get mangled symbol name from inside C++

Tags:

c++

linux

g++

How can I get the mangled name of a function from inside a C++ program?

For example, suppose I have a header:

// interface.h
#ifndef INTERFACE_H
#define INTERFACE_H
typedef void (*FooFunc)(int x, int y, double z, ...more complicated stuff...);
void foo(int x, int y, double z, ...more complicated stuff...);
#endif

and I have a client program that can load plugins that implement the interface:

// client.h
#include "interface.h"
void call_plugin(so_filename)
{
    void *lib = dlopen(so_filename, ...);
    // HOW DO I IMPLEMENT THE NEXT LINE?
    static const char *mangled_name = get_mangled_name(foo);
    FooFunc func = (FooFunc)dlsym(lib, mangled_name);
    func(x, y, z, ...);
    dlclose(lib);
}

How do I write the get_mangled_name function to compute the mangled name of the foo function and return it as a string?

One method that comes to mind is to compile interface.o and use nm -A interface.o | grep foo to get the mangled name then copy-and-paste it as a hard-coded string into client.h, but that feels like the wrong approach.

Another method that comes to mind is to force interface.h to be a pure C interface where I marshal all of the C++ data into a big blob that's sent through a C interface and then have the C++ objects reconstructed on the other side. This also feels suboptimal.

Edit

Note that this is actually a distinct question from Getting mangled name from demangled name. I'm wondering how to get at the mangled value from inside of C++ itself, at compile time, from type information available to the compiler, given a C++ identifier's name only.

like image 724
Mr Fooz Avatar asked Nov 09 '22 16:11

Mr Fooz


1 Answers

You can prevent mangling by declaring your functions as extern "C":

// interface.h
#ifndef INTERFACE_H
#define INTERFACE_H
typedef void (*FooFunc)(int x, int y, double z, ...more complicated stuff...);
extern "C" void foo(int x, int y, double z, ...more complicated stuff...);
#endif

... and making sure you #include that header file in all the source files that make up your shared library, as this declaration affects both the definition and references to the relevant function emitted by the compiler. Note that your function signature can still use non-POD types, such as std::string.

like image 161
davlet Avatar answered Nov 15 '22 04:11

davlet