【问题标题】:Why's the linker not finding just a single (present) method in a library?为什么链接器没有在库中只找到一个(存在)方法?
【发布时间】:2015-11-16 23:55:14
【问题描述】:

所以我最近开始使用一个名为 libgambatte (github) 的库,一切都很顺利,直到链接器开始抱怨一个方法的未定义引用。真正奇怪的是它会找到该对象的所有其他方法!参数的类型是正确的(我从库中包含的工作程序中复制了它们)。

代码如下:

制作输出

g++  -Wall -Wextra -g3 -I../libgambatte/include -I../common  -c -o test.o test.cpp
g++ test.o -L../libgambatte -lgambatte -lz -o test
test.o: In function `main':
<REDACTED>/src/test.cpp:12: undefined reference to `gambatte::GB::runFor(unsigned long*, long, unsigned long*, unsigned long&)'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'test' failed
make: *** [test] Error 1

生成文件

CPPFLAGS=-Wall -Wextra -g3 -I../libgambatte/include -I../common
LDFLAGS=-L../libgambatte -lgambatte -lz

.PHONY=all clean

all: test

test: test.o
    $(CXX) test.o $(LDFLAGS) -o test

clean:
    rm -f test.o test

nm ../libgambatte/libgambatte.a | grep runFor的输出

0000000000007a20 T _ZN8gambatte3CPU6runForEm
0000000000000190 T _ZN8gambatte2GB6runForEPjlS1_Rm
                 U _ZN8gambatte3CPU6runForEm

test.cpp的来源

#include <gambatte.h>

using namespace std;

int main(void){
    gambatte::uint_least32_t audiobuf[1234];
    gambatte::uint_least32_t framebuf[1234];
    size_t samples = 1234;
    unsigned gb_width = 160;
    gambatte::GB gb;

    gb.runFor(framebuf, gb_width, audiobuf, samples);

    return 0;
}

runFor方法声明

std::ptrdiff_t runFor(gambatte::uint_least32_t *videoBuf, std::ptrdiff_t pitch,
                      gambatte::uint_least32_t *audioBuf, std::size_t &samples);

gambatte::uint_least32_t的定义

#ifdef HAVE_CSTDINT

#include <cstdint>

namespace gambatte {
    using std::uint_least32_t;
    using std::uint_least16_t;
}

#elif defined(HAVE_STDINT_H)

#include <stdint.h>

namespace gambatte {
    using ::uint_least32_t;
    using ::uint_least16_t;
}

#else

namespace gambatte {
#ifdef CHAR_LEAST_32
    typedef unsigned char uint_least32_t;
#elif defined(SHORT_LEAST_32)
    typedef unsigned short uint_least32_t;
#elif defined(INT_LEAST_32)
    typedef unsigned uint_least32_t;
#else
    typedef unsigned long uint_least32_t;
#endif

#ifdef CHAR_LEAST_16
    typedef unsigned char uint_least16_t;
#else
    typedef unsigned short uint_least16_t;
#endif
}
#endif

抱歉,代码太长了。

【问题讨论】:

  • 如果你明确地使用unsigned long而不是uint_least32_t会发生什么?
  • @Jason 没有任何变化,我刚刚尝试过,一切都保持不变..
  • 您的 gcc 包最近有更新吗?你确定libgambatte是用相同的工具版本编译的吗? std::ptrdiff_t gb_width 而不是 unsigned gb_width 有什么不同吗?
  • @grek40 最近没有更新,我使用相同的工具和相同的库文件来编译库中包含的工作程序和我的。使用ptrdiff_t 没有区别,我使用unsigned 因为工作程序使用相同的类型。

标签: c++ linker-errors ld


【解决方案1】:

我发现了问题:正如您在gambatte::uint_least32_t 的定义中看到的那样,类型定义是基于某些常量的存在。我的问题出现了,因为库(和包含的程序)是用-DHAVE_STDINT_H 编译的,因此将gambatte::uint_least32_t 定义为不同的类型,导致链接器找不到正确的签名;使用-DHAVE_STDINT_H 编译解决了我的问题。

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多