前几天在重编项目底层库的时候,遇到了一些奇怪的问题.
首先说一下环境,我们项目用的是vs2005做开发工具,项目用到了一些开源的第三方库,比如zlib,log4cxx,mysql,等等.
因为想着升级到vs2015,所以前几天就想着把用的库文件全部和最新的代码做一次更新匹配,免得到时候出现了问题因为库和代码对不上查不了bug.
在全部重编完库后(我们一些是编译成lib,一些是dll),放到工程文件编译开始报错, 未解决的外部符号,比luaplus的其中一个lua_tostring函数,我在仔细用dumpbin查看了luaplus.lib的到处函数后发现函数是存在的,但是编译后的函数名有了不同,一开始我以为是调用约定的问题,跑去看了cdecl,stdcall,fastcall的函数命名方式,发现并无问题.
后来又发现了/tc,/tp,/TC,/TP的不同,后来终于发现了问题。
其实问题到关键在于/TC和extern“C”
一开始库文件的配置是全部/TC,cdecl,项目工程也是/TC,cdecl
但是代码里应用的一些头文件里面还是有extern“C”的标识,
也就是说我的库文件在编译后里面的函数命名全部是C++格式的,但是在项目工程链接的时候因为有了extern"c"的表示,它实际上是按照c的方式去查找这些函数的,比如上面的那个lua_tostring函数,这当然找不到啦,然后就报了这个经常出现的错误“未解决的外部符号”,虽然我是一遍又一遍的确认了头文件有包含,库文件也有包含,但是依然报错,最后问题居然是这个,也只能怪自己对于vs编辑器了解不够透彻,不明白/tc,/TC的配置,以为全部都是/TCj就能保持一致,不会有问题,错了啊。
后来在把所有的库项目的/TC改成默认后,问题就不复存在了。
这里还额外说一句,lib工程是可以依赖另一个lib的,但dll却无法依赖另一个dll,exe既可以依赖lib,又可以依赖dll,所以在链接程序时大家可以从这方面查找相关bug。
这只是随笔,想到什么就说什么了,见谅。