2011-05-17 169 views
4

我創建了一個名爲InterfaceLayer.so 當我打電話納米InterfaceLayer我得到一個象徵符號,是動態的lib:奇怪的符號名

00000e28 T _Z5startv 

的例子,但我希望它是隻「start」作爲我在代碼中定義的函數的名稱..這很糟糕,因爲當我嘗試用dlsym()打開時,它不起作用。

任何線索?

TKZ

回答

8

這是因爲C++名稱重整

nm -C 

demangles他們。

爲了防止名稱重整,

  • 使用C編譯器(gcc,不克++),命名的源文件的.c(未.CPP)
  • 或聲明爲extern 「C」:

my.h

extern "C" 
    { 
     void start(); 
     void finish(); 
    } 

這將給他們 「C」 鏈接,這意味着他們不能超載,不能按引用傳遞,沒有C++ :)

+0

快速和acurate。謝謝! – Lelo 2011-05-17 19:44:29

+1

可悲的是無法在OSX上工作。 – Timmmm 2017-01-25 12:06:59

2

聽起來像C++ name mangling

+2

我經常使用* C++ filt *當我需要demangle他們:'C++ filt _Z5startv' – karlphillip 2011-05-17 19:33:32

+0

nm myApp | C++ filt;#Is正是我所需要的,我在OSX和XCode上使用了它的扭曲的GNU工具堆棧,它不支持nm-C。謝謝@karlphillip – matiu 2011-09-10 21:26:56

1

正如其他答案所提到的,這可能是由於C++的名稱改變。如果你希望這個符號可以通過它的'unmangled'名稱來訪問,並且它用C++實現,你需要我們extern "C"告訴C++編譯器它有一個C鏈接。

在具有函數原型的頭,你會想是這樣的:

#if defined(__cplusplus) 
extern "C" { 
#endif 

// the prototype for start()... 


#if defined(__cplusplus) 
} 
#endif 

這將確保如果函數是使用C++編譯器,它會在聲明中得到extern "C" ,並且如果它被C模塊使用,它不會被extern "C"說明符所迷惑。

如果在函數定義之前包含標題,那麼您在.cpp文件中的實現不需要那些東西。它將使用從前面的聲明中看到的鏈接規範。不過,我更喜歡用extern "C"來裝飾函數定義,只是爲了確保所有內容都是同步的(請注意,在.cpp文件中,您不需要預處理的東西 - 它總是會被編譯爲C++。)