2011-05-17 178 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++。)