终于解决了困扰我至少5个小时的链接错误
今天就要拿出程序来,可偏偏就是编译不过!
链接错误!又见链接错误:
error LNK2001: unresolved external symbol xxxxxxxxxxxxxxxxxx
我遇见这个错误当然不止一次了,想象中不难解决,我按照“定式”逐个确认:被引用的lib已经编译,lib所在目录已正确设置,lib已加入到“Object/library modules”中,被引用的lib和当前工程使用的是相同的“Use run-time library”设置(“Multithreaded DLL”)……
实在没有办法了,我一遍遍的“Rebuild All”,一遍遍地检查各项设置,我知道这样很傻,可又能怎么样呢,我已经束手无策了啊,我只希望能碰到一次好运气,让它链接通过吧!
无论怎么重复,结局是一样的。
也上网搜索了几遍,出现同样问题的倒是不少,但我并未从中找到解决我的问题的答案,哪怕是线索。
后来逐项核对VC项目配置,终于发现了症结所在:在“Ignore libraries”多填了“msvcrt.dll”!(Link - Category:Input)
哦,原来如此,怪不得有那么多C标准库函数都被视为“unresolved external symbol”。
真应了那句老话(是老话吗?不确认),看似非常复杂的问题,往往可以通过非常简单的手段解决。我还要补上半句:找到简单手段的过程也往往非常艰辛!
这又让我想前了前几天在Linux下用GCC编译时遇到的奇怪的问题:编译链接均成功,但编译出的so无法被加载,dlopen()失败,dlerror()返回“找不到符号”之类的东东。它所找不到的符号明明是在某个静态库.a中,况且已经链接通过了呀。系统:Ubuntu6.10,GCC:4.1.2。GCC命令行是:
gcc -shared -L. -I. x.a y.a z.a a.o b.o c.o -o my.so
最终的解决方案实际上这很简单,就是把“-o my.so”往前放,把“x.a y.a z.a”往后放,即改为:
gcc -shared -o my.so -L. -I. a.o b.o c.o x.a y.a z.a
这个问题困扰了我好几天,是在很偶然的机会下才找到了解决办法。
回过去想一下,用第一个命令行链接时,那些静态库.a并没有被编译进so中,用 nm 命令查看也证实了这一点。
我对GCC以及LINUX下编程不太熟悉,不知道GCC的参数前后顺序有没有关系,不知道第一种写法算正确呢,还是非法呢,还是GCC的BUG?
写出这一点,希望能给遇到类似问题的朋友一些启发。
注:上面给出的GCC编译链接命令行是经过精简后的,真实的编译链接命令是在Makefile中由多个宏参数组合而成的,用到了大量的.o和大量的.a,以及其它选项,比这要复杂的多。