Linux 如何避免多重定义链接错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4654365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to avoid multiple definition linking error?
提问by ban
Beside moving the hello()
function into another source (.cpp) file or renaming the function. Is there any other methods to avoid the linking error?
除了将hello()
函数移动到另一个源 (.cpp) 文件或重命名函数之外。有没有其他方法可以避免链接错误?
staticLibA.h
静态库
#ifndef _STATIC_LIBA_HEADER
#define _STATIC_LIBA_HEADER
int hello(void);
int hello_staticLibA_only(void);
#endif
staticLibA.cpp
静态库文件
#include "staticLibA.h"
int hello(void)
{
printf("\nI'm in staticLibA\n");
return 0;
}
int hello_staticLibA_only(void)
{
printf("\nstaticLibA: hello_staticLibA_only\n");
return 0;
}
output:
输出:
g++ -c -Wall -fPIC -m32 -o staticLibA.o staticLibA.cpp
ar -cvq ../libstaticLibA.a staticLibA.o
a - staticLibA.o
staticLibB.h
静态库
#ifndef _STATIC_LIBB_HEADER
#define _STATIC_LIBB_HEADER
int hello(void);
int hello_staticLibB_only(void);
#endif
staticLibB.cpp
静态库文件
#include "staticLibB.h"
int hello(void)
{
printf("\nI'm in staticLibB\n");
return 0;
}
int hello_staticLibB_only(void)
{
printf("\nstaticLibB: hello_staticLibB_only\n");
return 0;
}
output:
输出:
g++ -c -Wall -fPIC -m32 -o staticLibB.o staticLibB.cpp
ar -cvq ../libstaticLibB.a staticLibB.o
a - staticLibB.o
main.cpp
主程序
extern int hello(void);
extern int hello_staticLibA_only(void);
extern int hello_staticLibB_only(void);
int main(void)
{
hello();
hello_staticLibA_only();
hello_staticLibB_only();
return 0;
}
output:
输出:
g++ -c -o main.o main.cpp
g++ -o multipleLibsTest main.o -L. -lstaticLibA -lstaticLibB -lstaticLibC -ldl -lpthread -lrt
./libstaticLibB.a(staticLibB.o): In function `hello()':
staticLibB.cpp:(.text+0x0): multiple definition of `hello()'
./libstaticLibA.a(staticLibA.o):staticLibA.cpp:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [multipleLibsTest] Error 1
回答by Foo Bah
The linking error specifically refers to hello. This shows up because both libraries provide definitions of "hello". There is no other linking error here.
链接错误特指hello。这是因为两个库都提供了“hello”的定义。这里没有其他链接错误。
You can either put hello in a separate library, have hello reside in a separate library, or just have the executable link against a hello object file [hello.o]
您可以将 hello 放在单独的库中,让 hello 驻留在单独的库中,或者只将可执行链接指向 hello 对象文件 [hello.o]
回答by forsvarir
Since you appear to own both libraries, it's unclear why you can't rename the function...
由于您似乎拥有这两个库,因此不清楚为什么不能重命名该函数...
In your main
, you have this line:
在您的main
,您有这一行:
hello();
What are you expecting to happen here, if you make the linking error go away? Should it call the implementation in LibA
, or LibB
? Relying on the order that you pass the libraries to the linker to determine which function gets linked seems like a very bad idea. In a real example, what would happen if your hello_staticLibB_only
function was calling hello()
? It could end up calling the version of the function that's in the other library...
如果您使链接错误消失,您希望在这里发生什么?它应该在LibA
, 或 中调用实现LibB
吗?依靠将库传递给链接器的顺序来确定哪个函数被链接似乎是一个非常糟糕的主意。在一个真实的例子中,如果你的hello_staticLibB_only
函数正在调用会发生什么hello()
?它最终可能会调用另一个库中的函数版本......
As you're using g++
, you should consider putting your library functions into a namespace
(they're designed to help you avoid this kind of nameing conflict). This would allow both your code and the linker to tell the difference between the methods.
当您使用 时g++
,您应该考虑将您的库函数放入 a namespace
(它们旨在帮助您避免这种命名冲突)。这将允许您的代码和链接器区分方法之间的区别。
Following this approach for LibA
, you would have:
遵循这种方法LibA
,您将拥有:
staticLibA.h
静态库
#ifndef _STATIC_LIBA_HEADER
#define _STATIC_LIBA_HEADER
// Declare namespace to keep library functions together
namespace LibA {
int hello(void);
int hello_staticLibA_only(void);
}
#endif
staticLibA.cpp
静态库文件
#include "staticLibA.h"
#include <stdio.h>
// Indicate that contained function definitions belong in the LibA namespace
namespace LibA {
int hello(void)
{
printf("\nI'm in staticLibA\n");
return 0;
}
int hello_staticLibA_only(void)
{
printf("\nstaticLibA: hello_staticLibA_only\n");
return 0;
}
}
main.cpp
主程序
// These declarations would usually be in a header... but I've left
// them here to match your sample code...
// declare relevant functions to belong to the LibA namespace
namespace LibA{
extern int hello(void);
extern int hello_staticLibA_only(void);
}
// declare relevant functions from LibB (note they are not
// in a namespace)
extern int hello(void);
extern int hello_staticLibB_only(void);
int main(void)
{
// Explicitly call the hello from LibA
LibA::hello();
// Call the other library function (also from LibA)
LibA::hello_staticLibA_only();
// Call library functions from LibB (note they don't require a namespace
// because I haven't updated it to have one)
hello();
hello_staticLibB_only();
return 0;
}