为什么链接器不能在库中找到单个(现有)方法?

时间:2015-11-16 23:55:15

标签: c++ linker-errors ld

所以我最近开始使用一个名为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

很抱歉这长码。

1 个答案:

答案 0 :(得分:1)

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