1 错误提示

error LNK2019: 无法解析的外部符号 __imp_FreeImage_Allocate,该符号在函数 "public: bool __cdecl colmap::Bitmap::Allocate(int,int,bool)" (?Allocate@Bitmap@colmap@@QEAA_NHH_N@Z) 中被引用。

2 错误分析与解决

该错误是在“C++项目属性 ---- 链接器 ----- 输入 ---- 附加依赖项”中,没有输入第三方静态链接库的时候,报错的。需要指明的是,你有时候忘记输入某些lib,工程编译的时候不会报错,而会在链接的时候出错。

此时,只需要输入对应debug/release版本的lib库即可。

3 补充

各个动态链接库的编译方式必须统一才行,要不然很容易对库函数的引用产生冲突。简单来说就是,如果使用的第三方函数库编译方式采用/MD,那么主工程也应该使用/MD。我使用了libevent,而主工程默认采用/MT,所以需要忽略一大堆的函数库。

MSDN中对于在不同的配置下Link的LIB作了说明:

编译器会自动根据编译选项,选择对应的LIB文件。一般情况下这不会出现问题。然而,在部分情况下,一旦你的程序的各个部分(LIB, OBJ…)并非由相同的编译选项编译出,而Link在一起的话,会出现各种各样的看似很难解决的问题,这类问题主要以重复定义的错误形式存在,通常的解决方法也很简单,就是选择同样的编译选项进行编译之后再Link。

3.1 链接方式

1、为什么选择/MD,不选/MT?
(1)程序就不需要静态链接运行时库,可以减小软件的大小;

(2)所有的模块都采用/MD,使用的是同一个堆,不存在A堆申请,B堆释放的问题;

(3)用户机器可能缺少我们编译时使用的动态运行时库。(补充:如果我们软件有多个DLL,采用/MT体积增加太多,则可以考虑/MD + 自带系统运行时库)

选择/MD要注意“多个模块选择不同版本运行库”的问题:

  1. 多个dll被一个exe LoadLibrary加载,如果这些dll使用的运行时库是不同的,那么可能出现加载失败,原因可能是旧版本的运行时库已经在了,而某个dll它需要的是新版本的运行时库,旧版本不符合要求。

  2. 如果工程里所有的模块都是自己写的或者可以完全控制的,那么这个问题不难解决,只需要在工程设置里都设置/MD,然后在相同的环境下编译一次就行。但是假如这个模块是外界提供的呢?

  3. 可能存在这种情况:A动态库使用了B静态库,B静态库使用了C动态库,B静态库是外界提供的,我们要使用它,但无法修改它,我们也无法接触到C动态库。如果C动态库使用的运行时库版本跟编译A动态库的本地使用的不一致,那么A动态库里的嵌入信息就会记录两个不同版本的运行时库,它被加载的时候,可能会选择版本新的。假设A动态库被一个exe LoadLibrary加载,而这个exe本身的运行时库是旧的,这样就会导致A动态库加载失败,即便把新的运行时库拷贝到目录下也不行,因为exe这个进程已经加载了那个旧的运行时库。这时候必须使用manifest文件指定嵌入到A动态库里的运行时库为某个版本,忽略掉C动态库使用的运行时库版本。

  4. 这个问题挺复杂的,我心思没去验证windows的PE文件加载会对运行时库做什么样的优先选择、运行时库在静态库里的记录…。只要记住,给外界使用的组件版本尽量避免使用/MD(这样会导致膨胀吗?据说,安装包可以做字节流式压缩)。

  5. 附上另一个问题:静态库的依赖关系:exe–>libA–>libB,现在不想让exe接触到libB,于是把libA的librarian选项–>General选项–>Link Library Dependencies设置为Yes,这样即可,libA会包含libB,exe只需要接触libA。另外需要特别注意,libA对libB的依赖只需要且只能在Solution的Project Dependencies里设置,如果在libA的代码里写了”#pragma comment(lib, “libB.lib”)”,会导致exe在link libA的时候提示找不到libA。如果exe还出现link错误,那一定是VS抽筋了:)2、为什么选择/MT,不选择/MD?(1)有些系统可能没有程序所需要版本的运行时库,程序必须把运行时库静态链接上。

2、为什么选择/MT,不选择/MD?
(1)有些系统可能没有程序所需要版本的运行时库,程序必须把运行时库静态链接上。

(2)减少模块对外界的依赖。

选择/MT 时存在一个“堆空间释放”的问题:

不同的模块各自有一份C运行时库代码、或者根本没有C运行时库,导致了各个模块会有各自的堆。如果在A堆中申请空间,到B堆中释放就会有崩溃,在模块A申请的空间,必须在模块A中释放。

多个模块,必须选择相同的运行时库。

Summary

知道各个不同的LIB代表的版本信息非常重要,可以帮助快速定位问题
在编程的时候,一定要把所有的项目的编译选项(是静态链接Runtime库还是动态链接Runtime库,Debug/Release)配置成一样的。如果部分LIB/OBJ是由第三方提供(OBJ情况很少见),一般情况下只能调整自己的编译选项,除非你可以要求第三方提供其他版本的编译好的LIB
在发布可重用的静态LIB库供其他人调用的时候,最好对应不同的编译选项,乃至VC版本,提供不同版本的LIB。VC自己的Runtime就是最好的例子。

参考

C++工程编译之“error LNK2001: 无法解析的外部符号”

 

C++项目链接出错, error LNK2019: 无法解析的外部符号 __imp_xxxx_Allocate,该符号在函数 "xxxx" (xxxx) 中被引用的更多相关文章

  1. 使用SDL2出现 “error LNK2019: 无法解析的外部符号 _SDL_main,该符号在函数 _main 中被引用” 时的可能错误记录

    这几天在使用SDL2,之前一直都没有错,直到上午把项目搬了个地方.结果一直出现 “error LNK2019: 无法解析的外部符号 _SDL_main,该符号在函数 _main 中被引用” . 看了网 ...

  2. error LNK2019 无法解析的外部符号------类模板和内敛函数

    今天用类模型实现一个单链表,开始是.h和.cpp将类模板的声明与实现分开写的,结果总是报错: 错误 error LNK2019: 无法解析的外部符号 ?$SingleList@H@@QAE@XZ),该 ...

  3. vs LNK2019 无法解析的外部符号 ***,该符号在函数 WinMain 中被引用

    一般链接错误都是因为包含头文件与lib库不匹配(无导出函数.lib库的release debug版本混乱.库引用的优先级.编译器设置mt/mtd等等)造成的. 错误    LNK2019    无法解 ...

  4. c++ 链接mysql:error LNK2019: 无法解析的外部符号

    使用VS2012编译项目报错如下: error LNK2019: 无法解析的外部符号 _mysql_real_connect@32,该符号在函数 _main 中被引用 error LNK2019: 无 ...

  5. error LNK2019: 无法解析的外部符号 ___glutInitWithExit@12,该符号在函数 _glutInit_ATEXIT_HACK@8 中被引用 1>GEARS.obj : er

    转: http://blog.csdn.net/bill_ming/article/details/8150111 opengl的高级菜鸟问题 看了一本书<OpenGL三维图形系统开发与应用技术 ...

  6. error LNK2019: 无法解析的外部符号

    前些日子电脑系统崩了,重装了了下,原有的项目环境得重新搭建,总是在链接时提示:error LNK2019: 无法解析的外部符号………… 起初以为是库没包含全,可发现不是 有想了下可能是库的包含次序有问 ...

  7. ACE_TEST1.obj : error LNK2019: 无法解析的外部符号

    ACE_TEST1.obj : error LNK2019: 无法解析的外部符号 "int __cdecl ace_main_i(int,char * * const)" (?ac ...

  8. 一个小错误:error LNK2019: 无法解析的外部符号 "public: __thiscall Turtle::~Turtle(void)" (??1Turtle@@QAE@XZ),该符号在函数 _main 中被引用

    昨天在撸代码的时候遇到了一个十分蛋疼的错误 : 错误: 1>3.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall Turtle::~ ...

  9. error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> >

    1,VS2013: 错误 1 error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_trai ...

随机推荐

  1. ggplot常见语法汇总查询

    主图 散点图 柱状图 折线图 小提琴图 点图 进化树 圈图 Alluvial图 Sankey Diagram plot(getSankey(colData(muraro)$cell_type1, mu ...

  2. 开启Nginx监控 with-http_stub_status_module

    1.开启监控with-http_stub_status_module ./configure  --with-openssl=/usr/local/ssl  --with-http_stub_stat ...

  3. pg执行计划分析小笔记

    开发同事问,为什么一个标量子查询,放在where子句后进行大小判断,比不放在where子句后进行判断大小运行的更快?按道理加了一次判断,不是应该变慢么? 把语句拿过来,看了一下两个语句的执行计划: 语 ...

  4. ISO/IEC 9899:2011 条款6.10.2——源文件包含

    6.10.2 源文件包含 约束 1.一个#include指示符应该指定一个能被实现处理的头文件或源文件. 语义 2.一个预处理指示符如下形式 #    include    <h-char-se ...

  5. navicat for mysql 如何设置字段唯一

    在设计表时,上面会有索引这一项 点开,在栏位处选择你需要设置的字段,然后选择unique索引类型即可 望采纳,谢谢!

  6. 002-maven开发Java脚手架archrtype【如无定制开发,请直接看3.3使用】

    一.概述 项目基础构建需要:项目结构,spring框架,orm,连接池,数据库,单元测试等等. 上述即使复用:001-脚手架发展,基础代码结构+mybatis代码生成,基础代码结构,也需要修改成自己单 ...

  7. 采用EasyDSS视频点播服务器搭建企业私有化的音视频多媒体、短视频、视频服务网站与管理后台

    最近有越来越多的用户咨询关于视频点播的功能,主要需求就是集中于如何搭建专属的私有化视频点播平台: 实现的功能类似于,对应自身拥有的视频文件,需要发布到一个网站,其他用户都可以实现点播观看. 针对于类似 ...

  8. node.js生成验证码及图片

    示例代码: var svgCaptcha = require('svg-captcha'); var fs = require('fs'); var codeConfig = { size: 5,// ...

  9. js 类型判断

  10. ucos III中任务之间的数据通信和任务划分

    1. 如果将关系密切(比如两个任务之间需要经常收发数据)的若干功能分别用不同的任务来实现,则需要进行大量的任务之间数据通信和同步通信,这系统来说是一个很大的负担.因此应该将关系密切的若干功能组合成一个 ...