2015-04-14 4 views
4

Как я могу получить искаженное имя функции из программы C++?получить искаженное имя символа изнутри C++

Например, предположим, что у меня есть заголовок:

// 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 

и у меня есть клиентская программа, которая может загружать плагины, которые реализуют интерфейс:

// 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); 
} 

Как я пишу get_mangled_name функцию вычислить искаженное имя функции foo и вернуть его как строку?

Один метода, который приходит на ум для компиляции interface.o и использовать nm -A interface.o | grep foo, чтобы получить искаженное имя затем скопировать и вставить его в качестве жесткой кодировки строки в client.h, но чувствует, как неправильный подход.

Другим методом, который приходит на ум, является заставить interface.h быть чистым интерфейсом C, где я собираю все данные C++ в большой блок, который отправляется через интерфейс C, а затем объекты C++, реконструированные с другой стороны. Это также кажется субоптимальным.

Редактировать

Обратите внимание, что это на самом деле отличный вопрос от Getting mangled name from demangled name. Мне интересно, как добраться до искаженного значения из самого C++, во время компиляции, из информации о типе, доступной компилятору, с учетом только имени идентификатора C++.

+0

Возможный дубликат [Получение измененного имени из развязанного имени] (http://stackoverflow.com/questions/12400105/getting-mangled-name-from-demangled-name) –

+0

Mangling является специфичным для платформы. Тем не менее, некоторые платформы следуют фиксированной ABI довольно стабильно, так что вы можете сами реализовать правила каретки. Вот правила [Itanium ABI mangling] (https://mentorembedded.github.io/cxx-abi/abi.html#mangling). –

+0

g ++ правила манипуляции находятся здесь: http://www.ofb.net/gnu/gcc/gxxint_15.html. Это не сложно реализовать. Жесткая часть - синтаксический анализ ввода - вам даже приходится учитывать, что вы не изменяете имя, если оно объявлено как «extern» C », - и если вы разбираете исходные файлы, которые могут быть удалены из метода, который вам интересен в. –

ответ

1

Вы можете предотвратить коверкая, объявляя свои функции, как 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 

... и убедившись, что вы #include файл заголовка во всех исходных файлах, которые составляют общую библиотеку, так как это влияет на объявление как определение, так и ссылки на соответствующую функцию, испускаемую компилятором. Обратите внимание, что ваша сигнатура функции может по-прежнему использовать не-POD-типы, такие как std :: string.

Смежные вопросы