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

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的实现的代码?
...全文
399 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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()的代码一样啊?

65,186

社区成员

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

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