生成静态库时,会链接进其调用的函数的代码吗?

parachutes30 2014-03-25 09:22:29
我感觉是不链接的,因为如下生成静态库成功了:
#include "stdafx.h"

void printf(char *p);

void out(int a)
{
printf("haha");
}


但库中的out函数是用不了的,工程设置附加依赖项填上上面生成的静态库文件,但用户程序链接时说找不到printf,代码如下:
#include "stdafx.h"

void out(int a);

int _tmain(int argc, _TCHAR* argv[])
{
out(1);
return 0;
}


那我把静态库改成如下重新生成,用户程序就链接成功了:
#include "stdafx.h"

#include <iostream>

void out(int a)
{
printf("haha");
}


我就搞不清了,我生成的静态库中到底有没有printf的实现的代码?
...全文
369 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-03-26
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
movsd 2014-03-26
  • 打赏
  • 举报
回复
静态库中只有你写的代码,你所调用的所有外部函数的代码都不会编译到静态库中。
movsd 2014-03-26
  • 打赏
  • 举报
回复
引用 9 楼 mougaidong 的回复:
那 extern template 呢?
引用 8 楼 movsd 的回复:
[quote=引用 3 楼 mougaidong 的回复:] STL的代码呢? [quote=引用 1 楼 movsd 的回复:] 静态库中只有你写的代码,你所调用的所有外部函数的代码都不会编译到静态库中。
对于模板,其实是编译器按预定的格式为你生成了一段代码,这段代码视为你写的代码的一部分,会被编译进你的目标文件中。[/quote][/quote] 外部模板本质是一样的,只是为了防止模板被多次实例化,提高编译和链接效率,因为如果在两个源文件中使用了同一类型模板,那么这个模板会被编译两次,分别加入到两个目标文件中,在链接时还要找到这两份相同的代码,然后去除多余,只保留一份,使用外部模板,可以指定模板只在一个源文件中编译,而其它源文件中声明为外部模板,不再编译,这样编译的链接的效率都可以得到提高。
qiminixi 2014-03-26
  • 打赏
  • 举报
回复
静态库说白了就是obj文件的集合。生成静态库时是没有进行链接的,链接操作是在生成可执行文件时进行的。
turing-complete 2014-03-26
  • 打赏
  • 举报
回复
那 extern template 呢?
引用 8 楼 movsd 的回复:
引用 3 楼 mougaidong 的回复:
STL的代码呢? [quote=引用 1 楼 movsd 的回复:] 静态库中只有你写的代码,你所调用的所有外部函数的代码都不会编译到静态库中。
对于模板,其实是编译器按预定的格式为你生成了一段代码,这段代码视为你写的代码的一部分,会被编译进你的目标文件中。[/quote]
movsd 2014-03-26
  • 打赏
  • 举报
回复
引用 3 楼 mougaidong 的回复:
STL的代码呢?
引用 1 楼 movsd 的回复:
静态库中只有你写的代码,你所调用的所有外部函数的代码都不会编译到静态库中。
对于模板,其实是编译器按预定的格式为你生成了一段代码,这段代码视为你写的代码的一部分,会被编译进你的目标文件中。
ztenv 版主 2014-03-26
  • 打赏
  • 举报
回复
理解不够深入吧
  • 打赏
  • 举报
回复
看一下 stdafx.h的文件内容,就明白了

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#define WIN32_LEAN_AND_MEAN		// 从 Windows 头中排除极少使用的资料
#include <stdio.h>
#include <tchar.h>
// TODO: 在此处引用程序需要的其他头文件
其实,你只要把你的 printf 声明去掉,就能够链接成功,不然,你试试
  • 打赏
  • 举报
回复
楼主还是没有区分开来编译和链接这两个过程呀! 在编译阶段,只要你的函数有正确的函数声明,不管有没有实现都是可以生成 相应的静态库文件,因为编译器假定,这个函数实现可以在其它的obj文件里有实现, 静态库文件,说白了就是obj文件打了包而已.
xiaohuh421 2014-03-26
  • 打赏
  • 举报
回复
void printf(char *p); 这里你自定义了一个printf, 却没有去实现它, 而你的out函数中又使用了这个函数, 那肯定就会提示找不到实现了, 当你去掉这掉这个void printf(char *p);函数声明, 你的out函数中使用的就是标准的C函数了, 所以能正常编译通过. 所以正像你说的, 你生成的静态库中确实没有void printf(char *p);这个自定义函数的实现, 只有C的标准printf的实现.
turing-complete 2014-03-26
  • 打赏
  • 举报
回复
STL的代码呢?
引用 1 楼 movsd 的回复:
静态库中只有你写的代码,你所调用的所有外部函数的代码都不会编译到静态库中。
图灵狗 2014-03-26
  • 打赏
  • 举报
回复
1、你的静态库不会包含printf的实现代码,它依然在C标准库中; 2、void printf(char *p)这样的声明与C标准库的接口不一致。
引用 楼主 u010928112 的回复:
我感觉是不链接的,因为如下生成静态库成功了:
#include "stdafx.h"

void printf(char *p);

void out(int a)
{
	printf("haha");
}
但库中的out函数是用不了的,工程设置附加依赖项填上上面生成的静态库文件,但用户程序链接时说找不到printf,代码如下:
#include "stdafx.h"

void out(int a);

int _tmain(int argc, _TCHAR* argv[])
{
	out(1);
	return 0;
}
那我把静态库改成如下重新生成,用户程序就链接成功了:
#include "stdafx.h"

#include <iostream>

void out(int a)
{
	printf("haha");
}
我就搞不清了,我生成的静态库中到底有没有printf的实现的代码?
  • 打赏
  • 举报
回复
引用 13 楼 u010928112 的回复:
[quote=引用 6 楼 wangdahu888 的回复:] 看一下 stdafx.h的文件内容,就明白了

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#define WIN32_LEAN_AND_MEAN		// 从 Windows 头中排除极少使用的资料
#include <stdio.h>
#include <tchar.h>
// TODO: 在此处引用程序需要的其他头文件
其实,你只要把你的 printf 声明去掉,就能够链接成功,不然,你试试
用户程序cpp不需要声明printf()吧。静态库的cpp需要printf()的声明,否则过不了编译。 我也试过了,和stdio.h,tchar.h都没有关系。 [/quote] 当然有关系了,你引用了#include <iostream>,你顺着这个头文件往上找,会找到stdio.h的引用的,说白了,还是使用标准库里的printf
parachutes30 2014-03-26
  • 打赏
  • 举报
回复
引用 4 楼 xiaohuh421 的回复:
void printf(char *p); 这里你自定义了一个printf, 却没有去实现它, 而你的out函数中又使用了这个函数, 那肯定就会提示找不到实现了, 当你去掉这掉这个void printf(char *p);函数声明, 你的out函数中使用的就是标准的C函数了, 所以能正常编译通过. 所以正像你说的, 你生成的静态库中确实没有void printf(char *p);这个自定义函数的实现, 只有C的标准printf的实现.
我生成静态库lib中没有C标准库printf()的实现吧?
parachutes30 2014-03-26
  • 打赏
  • 举报
回复
引用 6 楼 wangdahu888 的回复:
看一下 stdafx.h的文件内容,就明白了

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#define WIN32_LEAN_AND_MEAN		// 从 Windows 头中排除极少使用的资料
#include <stdio.h>
#include <tchar.h>
// TODO: 在此处引用程序需要的其他头文件
其实,你只要把你的 printf 声明去掉,就能够链接成功,不然,你试试
用户程序cpp不需要声明printf()吧。静态库的cpp需要printf()的声明,否则过不了编译。 我也试过了,和stdio.h,tchar.h都没有关系。 静态库cpp,工程设置不使用预编译头:
#include <iostream>

void out(int a)
{
	printf("haha");
}
用户程序cpp,工程设置不使用预编译头:
void out(int a);

int main(int argc, char* argv[])
{
	out(1);
	return 0;
}

怎么感觉像是静态库lib里面有printf()的代码一样啊?
通过该课程的学习,掌握0行代码写服务框架的服务发布,参数验证,代码生成功能,具备初步的使用能力 该项目本身设计的内容非常多,后期逐步开放讲解框架后期内容参考:https://mp.csdn.net/editor/html/112142371与Springboot+mybatis和Springboot+jdbctemplate对比:https://editor.csdn.net/md/?articleId=106091083框架主要功能:生成自定义sql模板文件1.一键生成数据库所有列表增、删、改、查接口通过代码生成器,一键生成增、删、改、查代码,分为有代码和无代码两种方式。有代码方式可以在需要业务封装直接调用生成代码进行业务组装。有代码方式和无代码方式都可以直接调用访问。2.可指定单表生成接口可以指定生成那张表的数据接口,以免对已有接口造成影响。3.一键生成接口测试postman调用文件生成postman调用接口,直接导入即可测试,不需要单独也写接口文档,也不需要使用swangger在代码中单独增加注释。字段长度类型,大小一目了然。4.可生成controller、service、dao、model、自定义sql、postman测试文件可以根据实际需要进行单独配置5.接口任意参数可自动配置多维度验证比如一个参数phone,在不需要编程的情况下,可以配置验证是否为空、长度、是否是电话号码6.数据接口可以任意组合形成新的接口比如、查询学校是一个接口、查询城市是一个接口,通常情况下在前端是需要两次请求,现在可以通过一次请求自动合并两个接口的数据结果,一次性返回。而这样的组合可以是无限个组合。7.所有接口参数均可自动封装比如查询省份接口,里面有10个参数,前端传入几个参数,便可自动封装几个参数。8.所有查询接口自带分页列表查询,有码方式和无码方式,均自带分页。9.通过简单sql的编辑即可完成服务发布只要写sql便可生成服务,不需要任何多余操作10.接口可以进行限流配置,可以根据ip、token、ak进行限流操作多维度自定义限流,可设置次数、限、限流方式11.所有接口可以进行签名认证所有接口通过接口sign签名认证12.所有接口可以进行登录认证限制,也可单独配置不需要登录认证可以指定接口单独授权不需要登录验证,比如验证码接口13.所有接口均可设置需要验证码验证所有的接口都可以通过参数配置设置短信验证码和图片验证码14.所有查询接口均可单独设置缓存所有接口皆可设置单独缓存,缓存周期15.所有接口均可监控访问次数同一接口访问次数记录,很容易监控服务访问,可以做更细致的服务优化16.所有接口均可记录访问日志,包括请求来源请求参数、获得结果入参出参所有访问皆有详细记录17.项目中的代码可以进行自动统计代码量一键统计代码量,包括前后端代码行数和体积18.可以自动进行数据统计,可配置单表数据量统计、也可以配置定任务数据统计自动表数据统计,方便做BI可视化报表,不需要开发直接配置即可19.可进行跨域设置跨域通过配置文件配置20.可进行IP禁用对于恶意访问ip进行封禁21.可进行访问次数限制所有接口可以进行访问次数限制22.可进行访问来源设备、应用检查验证验证请求来源所用设备和请求发起的应用

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧