写在前面
在配置一些开源项目的时候,往往需要添加一些另外的开源库作为子模块,有时会遇到由于lib、dll版本问题配置失败,现将部分问题记录于此
先说结论
lib版本不对会导致:error LNK2019: 无法解析的外部符号_xxxxxx,函数 _xxxx 中引用了该符号
warning LNK4272: 库计算机类型“x64”与目标计算机类型“x86”冲突或者相反
fatal error LNK1120: 1 个无法解析的外部命令
什么是lib和dll
可参考此文【整理】Visual Studio如何导入lib, DLL文件
lib与dll的32与x64版本对应
现在很多的开源库都会提供32以及x64版本,配置时,它们所需的其它子模块的 lib文件以及dll文件也是要分对应,不然会出现编译成功,但链接失败、运行失败等问题
创建动态库项目
笔者使用的是visual studio2019创建项目
将framework.h pch.h pch.cpp移除
注意如果新建工程默认是.cpp,那么将.cpp文件更改为.c文件,并将以下代码粘贴至dllmain.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
__declspec(dllexport)//每个函数前都要加,输出lib文件
void dlltestprintf(int* p)
{
*p = 100;
printf("调用成功\n");
printf("调用成功\n");
return;
}
属性页预编译头选择不使用,预编译头文件为空
项目右键生成,此时是x86的平台也就是生成win32的lib与dll
生成成功
将平台更改为x64
同样属性里面更改预编译和预编译头文件
生成64位lib和dll成功
在文件目录下有debug和x64文件夹
debug里面是生成的win32文件
x64文件夹下是64位的文件
创建c++控制台应用程序
当前默认为x86平台也就是win32的
头文件添加新建项,名字和之前生成的lib文件名一致--------20210331_lib
将下列代码复制粘贴至.h文件
#ifndef _20210331LIB_H //如果没有定义,就定义
#define _20210331LIB_H
#ifdef __cplusplus //如果编译器使用c++规范,则按照C语言方式引用函数,避免c的语言被c++编译器编译不通过
extern "C" {
#endif
void dlltestprintf(int* p);
#ifdef __cplusplus
}
#endif
#endif
将以下代码粘贴至主程序
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "20210331_lib.h"
void main()
{
int a = 12;
dlltestprintf(&a);
printf("a:%d\n", a);
printf("hello....");
system("pause");
return;
}
注意如果新建工程默认是.cpp,那么将.cpp文件更改为.c文件
属性添加附加依赖项20210331_lib.lib
此时打开项目文件目录,将之前生成的debug(32位)文件夹下的lib dll pdb粘贴过来
从这里复制
粘贴
在visual studio;里面点击本地调试器
运行成功,可以看到程序调用动态库将a的值成功更改了
在文件目录下将之前生成的x64的3个文件复制过来覆盖掉win32的3个文件
在visual studio中将平台改为x64
同样在属性–附加依赖项里面添加20210331_lib.lib
点击本地调试器,同样运行成功
lib版本不对的结果
当平台是win32(x86)的,而文件目录下是x64的lib时,点击重新生成,一定要点击重新生成
可以看到:
1>20210331_libdlltest.obj : error LNK2019: 无法解析的外部符号 _dlltestprintf,函数 _main 中引用了该符号
1>20210331_lib.lib : warning LNK4272: 库计算机类型“x64”与目标计算机类型“x86”冲突
1>D:\a_programmer\C++\20210331_libtest\20210331_libdlltest\Debug\20210331_libdlltest.exe : fatal error LNK1120: 1 个无法解析的外部命令
1>已完成生成项目“20210331_libdlltest.vcxproj”的操作 - 失败。
有的时候只有error LNK2019: 无法解析的外部符号 _dlltestprintf,函数 _main 中引用了该符号,而没有类型冲突的提示,所以这时候就考虑是不是lib的版本不对了
同样,当平台是x64而动态库是32时
dll版本不对的结果
关于dll版本不对的情况,在这篇博客有说明,不再复述
win10+vs2013配置pcl 1.8.0
pdb文件的作用
简单来说,有pdb文件就可以对添加的动态库进行源码的调试
比如上面的win32(x86)平台正常使用的时候,加上断点,开始调试
F11进入函数,可以看到定位到了生成动态库的源码
参考及感谢
error LNK2019的一种原因
PDB符号文件详解
其余文中已列出
完
边学边用,如有错漏,敬请指正
--------------------------------------------------------------------------------------------诺有缸的高飞鸟20210331