2015-04-14 40 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

[從demangled名獲得重整名稱(http://stackoverflow.com/questions/12400105/getting-mangled-name-from-demangled-name) –

+0

忙玲的可能重複的是特定的平臺。也就是說,一些平臺非常穩定地遵循一個固定的ABI,因此您可以自己實施規則。以下是[Itanium ABI破壞規則](https://mentorembedded.github.io/cxx-abi/abi.html#mangling)。 –

+0

克++規則在這裏: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 

...,並確保你在#包括所有的源文件,使你的共享庫,頭文件,因爲這會影響申報編譯器發出的相關函數的定義和引用。請注意,您的函數簽名仍然可以使用非POD類型,例如std :: string。