Странное имя символа в выходных данных команды nm - PullRequest
5 голосов
/ 17 мая 2011

Я создал динамическую библиотеку с именем InterfaceLayer.so.Когда я звоню:

> nm InterfaceLayer

В качестве вывода я получаю несколько символов, которые выглядят так:

00000e28  T _Z5startv

, хотя я ожидал, что это будет " start ",так же, как имя функции, которую я определил в коде.

Есть какие-нибудь подсказки?

Tkz

Ответы [ 3 ]

11 голосов
/ 17 мая 2011

Это из-за искажения имени в C ++

nm -C

устраняет их.

Чтобы предотвратить искажение имени,

  • используйте компилятор C (gcc, не g ++), назовите ваш исходный файл .c (не .cpp)
  • или объявить extern "C":

.

my.h

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

Это даст им связь "C", то есть они не могут быть перегружены, не могут передаваться по ссылке, ничего c ++:)

3 голосов
/ 17 мая 2011
2 голосов
/ 17 мая 2011

Как уже упоминалось в других ответах, это, вероятно, из-за искажения имен в C ++.Если вы хотите, чтобы символ был доступен по его «неупорядоченному» имени, и он реализован в 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 вам не нужен материал предварительной обработки #ifdef - он всегда будет скомпилирован как C ++.

...