VC项目的主工程与它使用的Lib编译选项必须完全一致

由于使用了一个买来的,但没有源码的库,它是是MT和Unicode和MSVCRT编译的。所以我的主工程也必须使用这些选项。后来又新增了一个LIB,这个LIB必须自己编译,使用各种不同的项目配置,都会生成不同的LIB文件(从文件大小就可以看出来),一开始怎么样都要报错。最后问题终于解决了,最主要是设置UNICODE和MSVCRT,还设置了一些其它次要的选项,但不知道有没有影响。

报错:
1>librsync.lib(buf.obj) : error LNK2001: unresolved external symbol _fseeko
1>librsync.lib(trace.obj) : error LNK2001: unresolved external symbol _snprintf
其实当前编译器不一定找的是_fseeko,有可能是在找fseeko,因为这个_fseeko是函数以及被编译到obj后的结果,所有函数都会被加上下划线。
但是_snprintf却确实是在找_snprintf函数。


下面是对错误编译条件下的解释:
即,执行了:
#define HAVE_FSEEKO 1
#define HAVE_SNPRINTF 1
影响如下语句:
#ifdef HAVE_FSEEKO
#define fseek fseeko
#endif

#ifndef HAVE_SNPRINTF
# ifdef HAVE__SNPRINTF
# define snprintf _snprintf
# else
int snprintf (char *str, size_t count, const char *fmt, ...);
# endif
#endif

自己提问:
1:如果执行了#define fseek fseeko,那么实际上fseeko在msvcrt里不存在,为什么这个库仍然可以编译通过,而主程序无法连接这个库呢?不懂
2:如果执行了#define HAVE_SNPRINTF 1,那么snprintf又不一样,在snprintf.h里当场定义了一个函数。
也就是当前库不执行使用_snprintf函数,只使用自己定义的snprintf函数。然而主工程文件为什么找不到_snprintf函数?明明libcmt.lib和msvcrt.lib里都有这个函数啊。
难道是这个库的#define会对主工程起作用?

修改#define语句后的解释:
如果不执行#define HAVE_FSEEKO 1语句,那么正常使用fseek,这个函数在libcmt.lib和msvcrt.lib里都有,就没问题了。
如果不执行#define HAVE_SNPRINTF 1语句,那么执行define snprintf _snprintf语句,这样在msvcrt.lib找到它,也就编译没问题了。
如果不执行define snprintf _snprintf,那么使用库自定义的snprintf应该也没有问题。经过试验,确实没有问题。不过我觉得还是使用系统自带的函数更保险吧。

参考:
http://www.cnblogs.com/ljjphysics/archive/2011/06/24/2089417.html
https://msdn.microsoft.com/en-us/library/aa246416(v=vs.60).aspx
https://msdn.microsoft.com/en-us/library/aa298594(v=vs.60).aspx

你可能感兴趣的:(lib)