关于分析VC++的一个报错:error LNK2019: 无法解析的外部符号 __imp__。。。。。。

提前说明一下,我这个问题跟网上很多网友分享的问题不太一样,而且我认为导致问题出现的原因不重要,重点在于我分析这个问题的过程用到了一些知识,我认为值得分享一下。

博客中用的到工程:https://download.csdn.net/download/xundao255/11264177 

(如果有经验的话,完全可以根据博客内容自己创建工程,毕竟下载工程是需要C币的。补充:我没找到怎么免C币下载资源,这个C币是系统自动设置的)

一、先列出源码和错误截图

#include <stdio.h>

int PrintString(unsigned int);

int main()
{
	PrintString(3);

	return 0;
}

PrintString(unsigned int)函数是“lib.lib”静态库中实现的函数,所以需要在工程的属性中隐性导入这个静态库。注意:这个静态库是存放在当前工程的路径下的。下面是编译失败的结果图:

注意上面截图的粗框线标注的函数“_PrintString”,这是编译器编译代码后,会按照固定规则修改函数名。上面的错误信息表示找不到函数的实现,也就是定义。

二、再来看一下实验用的lib静态库代码

#include <stdio.h>

int __stdcall PrintString(unsigned int a)
{
	if (a < 5)
	{
		printf("小于5!\n");
	}
	else if (a == 5)
	{
		printf("等于5!\n");
	}
	else
	{
		printf("大于5!\n");
	}

	return 0;
}

这里放出代码,是为了说明函数什么功能,以及读者能自己做这个实验。在本博客中,我是假设不知道源代码的,只知道函数接口的声明而已和如何使用函数而已。

三、将步骤二中生成的“lib.lib”静态库放到步骤一的工程里面,使编译时能被找到。

四、当我发现出现了步骤一的错误后,逐渐排除了lib静态库没有成功加载的情况,也确定不是函数名写错了。此时,我就想看一下lib静态库的函数接口是什么样的,很有可能问题就出在这里。于是我再网上找到了方法,查看到lib静态库的接口信息:

Microsoft (R) COFF/PE Dumper Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\Users\Administrator\Desktop\input_lib\input_lib\lib.lib

File Type: LIBRARY

Archive member name at 8: /               
5D16D10D time/date Sat Jun 29 10:46:37 2019
         uid
         gid
       0 mode
      9B size
correct header end

    4 public symbols

      1B8 ??_C@_07COGGELOH@?P?$KB?S?Z5?$CB?6?$AA@
      1B8 ??_C@_07KIEDOMAO@?$LF?H?S?Z5?$CB?6?$AA@
      1B8 ??_C@_07MOINBNDI@?$LE?s?S?Z5?$CB?6?$AA@
      1B8 _PrintString@4

Archive member name at E0: /               
5D16D10D time/date Sat Jun 29 10:46:37 2019
         uid
         gid
       0 mode
      9B size
correct header end

    1 offsets

        1      1B8

    4 public symbols

        1 ??_C@_07COGGELOH@?P?$KB?S?Z5?$CB?6?$AA@
        1 ??_C@_07KIEDOMAO@?$LF?H?S?Z5?$CB?6?$AA@
        1 ??_C@_07MOINBNDI@?$LE?s?S?Z5?$CB?6?$AA@
        1 _PrintString@4

  Summary

         92C .debug$S
          64 .debug$T
          D7 .drectve
          18 .rdata
           4 .rtc$IMZ
           4 .rtc$TMZ
          8B .text

仔细看里面的函数接口显示为“_PrintString@4”,而不是“_PrintString”,这就解释清楚为什么找不到这个函数了。

关于如何查看静态库的接口,见我的另一篇博客:https://blog.csdn.net/xundao255/article/details/94128402

五、关于为什么“PrintString”编译成“_PrintString@4”,而不是“_PrintString”。

我们查看一下步骤二的代码:int __stdcall PrintString(unsigned int a),函数声明中加了“__stdcall”。这个关键字是给编译器看的,告诉编译器如何处理函数名称,后边的“@4”表示传参的数据类型的字节长度。详细说明见另一个大神写的博客:https://www.cnblogs.com/songfeixiang/p/3733661.html

六、找到问题所在,我们在步骤一的代码中的函数声明添加上这个关键字,编译成功并运行:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值