c++ - 如何避免多重定义链接错误?

标签 c++ linux linker g++ multiple-definition-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;
}

输出:

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;
}

输出:

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;
}

输出:

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

最佳答案

由于您似乎拥有这两个库,所以不清楚为什么不能重命名该函数...

在您的 main 中,您有这一行:

hello();

如果您让链接错误消失,您期望这里发生什么?它应该调用 LibA 还是 LibB 中的实现?根据将库传递给链接器的顺序来确定链接哪个函数似乎是一个非常糟糕的主意。在真实示例中,如果您的 hello_staticLibB_only 函数正在调用 hello() 会发生什么情况?它最终可能会调用其他库中的函数版本...

当您使用g++ 时,您应该考虑将您的库函数放入命名空间(它们旨在帮助您避免这种命名冲突)。这将允许您的代码和链接器区分方法之间的区别。

按照 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;
}

关于c++ - 如何避免多重定义链接错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4654365/

相关文章:

c++ - 在终端中更智能地查看程序输出 - 显示/隐藏较低优先级输出的按钮,允许向下钻取程序输出

c++ - C++ 头文件中的命名空间

c++ - constexpr 函数可能存在错误?

c++ - C中的编译时错误

c - LPC1788 - 引导加载程序和共享库

c++ - GNU GMP 中 mpz_class 的 sizeinbase

linux - 通过命令行与背景轨道连接 MP3

linux - 我可以使用什么 Linux api 来测量程序中某些函数的执行时间?

编译 64 位 Linux 的 32 位 GTK+ 应用程序

c++ - 链接错误,即使一切都在那里