2016-12-21 50 views
0

我用g++编译了一个库,我想用gcc来链接它。
问题是当链接反对我得到一个错误:如何删除共享库中符号周围的字符?

未定义的引用“functionName`

(functionName是在库中的函数名)

虽然功能存在于符号列表中,并在链接时指定gcc的路径。

这是因为该功能显示在列表中与周围的字符(我认为这是压倒一切?):

Z12functionNameiSt9__va_list

我知道要删除这些字符我应该围绕与extern "C"函数的声明。我这样做:

//header.hpp 
extern "C" int functionName(int argc, ...); 

但是周围的字符仍然出现在符号列表中的函数名称周围。这就是为什么gcc找不到它。

我为Linux手臂yokto交叉编译与arm-poky-linux-gnueabi-gccarm-poky-linux-gnueabi-g++ Ubuntu桌面16

上为什么没有被删除周围人物,我怎么能删除?我永远不会重写这个函数,所以如果这些都是重写的话,我不需要它们。


编辑:

解决。其声明中的函数签名与其定义中的签名不同......因此,关键字extern毫无用处。

int functionName(int argc, ...); //declaration 
int functionName(int argc, va_list args) //definition 
+0

也许你忘了'#include ' –

+0

@BasileStarynkevitch - 它包含 –

回答

1

这些字符是名称混搭。它们对函数签名进行编码,以便C++重载可以正常工作(例如,int foo(int)int foo(float)是不同的符号)。

如果您的API是C,您需要修复库以避免损坏。将其构建为C或在其代码中添加extern "C"。如果您的API旨在成为C++,请从头中删除extern "C"

如果mangled名称不匹配(不同的mangling),那么你可能有一个ABI兼容性问题。在那种情况下,试图解决链接问题是错误的解决方案。您需要确保使用与库相同的ABI构建代码。

c++filt工具应该能够将损坏的符号解码为签名。这对了解它们的区别很有用。

给你建库与g++,正在和gcc链接,很可能你想有一个C API和重建与地方extern "C"图书馆是你所需要的。

+0

API是c(没有类),但函数使用C++库。我在头文件中添加了'extern“C”''但是它并没有删除周围的字符。可能是因为函数签名有一个省略号('...')? –

+0

@AlaaM。不,它可以很好地处理省略号。你是否用'extern“C”'重建了图书馆?我从你的文章中了解到,链接器查找'functionName',但库包含'Z12functionNameiSt9__va_list',这意味着问题出现在库中。还要确保库实际上包含头文件,而不是简单地定义没有任何'extern“C”'的函数。 – Olivier

+0

正如我在帖子中所说的,我知道问题出在图书馆。问题是它仍然包含周围的字符 –

0

“周围的字符”实际上是name mangling。所以最好说重名

你或许应该加上

#ifdef __cplusplus 
extern "C" { 
#endif 

你的(公共)头文件的开头附近(你会在C和C++的公共子集更好的代码),并匹配

#ifdef __cplusplus 
}; // end of extern "C" 
#endif 

临近结束。另见this

你应该用这些东西(不仅仅是单独的函数)包装所有的公共头文件(也可能包含标准的C头文件)。

您可以编译gcc -H列出包含的标题或g++ -C -E获取预处理的表单(并检查它)。

+0

我不明白我刚才提到的那些不同之处是怎么样的?我已经添加了'extern“C''。 –