- UID
- 3
- 精华
- 积分
- 89
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
这是我和柏杨讨论这个问题的聊天记录,我觉得挺有意思的,就发到论坛上了。
Q: 我写了一个 Game.h 的类头文件,然后写了一个Game.cpp定义了了Game类的成员函数.我写了这两个文件,所以我是类实现程序员. 接下来,我把头文件Game.h交给写main函数的成员客户的代码程序员,并且提供了Game类的目标代码,但是我为了不让客户代码程序员知道Game成员函数是如何实现的,所以没把Game.cpp代码文件交给客户代码程序员.
那么,请问没有Game.cpp的客户代码程序员程序员是怎么通过使用我的Game.h 来完成main函数的编写的,Game.h头文件不是只有声明而已吗?
A: 这个问题在我刚学C语言的时候也困惑了我很久,我还在百度知道上提问了:
http://zhidao.baidu.com/question/126431256.html
A: 那个答案其实也勉强,没有切中要害
A: Game.h头文件中确实只有声明
但有声明就够了
A: 你还需要知道两点才能理解这个问题
Q: .cpp不用给他吗
Q: 哪两点
A: 1. 编译过程
2. 函数调用过程
Q: 是大三编译原理的那本书吗
A: 一个程序的编译过程是将每个源文件编译成目标文件(不考虑库),然后用链接器将各个目标文件链接起来。
Q: 是不是要了解编译原理
A: 不需要
这只是一些C语言的历史知识而已
Q: 嗯嗯
然后函数调用过程呢
A: 目标文件中包含了函数的地址,类似于这样的:
funcA 1000
funcB 1c00
符号表
Q: 嗯嗯,看的懂
A: 函数调用过程是指:函数(被调用者)和调用者之间的约定。
这个了解汇编后会深有体会,我也给你简单的介绍下
Q: 嗯嗯, 先给我指明了个方向!
A: C语言函数调用过程的约定使得调用者只要知道被调用函数的地址就可以了
A: 还有声明
地址 和 声明,调用者不需要知道函数的具体实现是什么,它就可以调用了
Q: 噢, 懂了!
A: 声明告诉了调用者有哪些参数(以及各个参数的字节数)
调用者根据声明压栈参数,然后call funcA,就可以调用过去了
A: 所以一个包含多个源文件的C项目,每个C文件是独立编译的,它只知道自己的实现和其他文件中函数的声明
Q: 嗯嗯
大概知道是怎么回事了
那是不是给了Game.h 后还要给Game.cpp,但是Game.cpp是以某种方式隐藏起来了,不过可以通过地址和声明去调用.
A: 不用给Game.cpp了,Game.h中有了声明,Game.obj中有函数地址
链接器能在obj文件中找到函数地址
A: obj文件是有特定格式的,里边有符号表,如果你深入研究的话你可以知道obj文件的这些结构自己写链接器
A: 也就是说obj文件不是你可能认为的只是一些低级的机器码指令,其中包含了很多其他的供调用者使用的信息。
Q: 我想我得去研究一下obj文件的具体情况
Q: 我感觉我还得问一个浅显的问题,如果我不给Game.cpp(或者以某种形式隐藏),只是简简单单的给了个.h文件,然后发这个文件给他人,然后在他人的电脑上可以用obj文件链接到我电脑上的Game.cpp文件?感觉不行啊
Q: 上面的意思我大概了解,不过对于Game.cpp的去处我不知道
A: 看来你对编译过程还没有完全理解
obj文件就行了,cpp文件完全不用了
A: obj文件中包含了cpp文件所有C/C++代码编译后的机器指令
cpp文件没有必要再出现了
A: obj文件包含了cpp文件所有C/C++代码编译后的机器码和供调用者使用的结构信息(符号表等等)。
Q: 噢,这样!
好像略懂了!
Q: 我再去仔细研究一下obj文件是如何使用的
A: 嗯,提供给调用者的只要.h文件和.obj文件就完全够了,没有.h文件的话,没有声明,不知道函数的参数,obj文件中是不包含参数信息的,所以.h文件是缺少不了的。
Q: 嗯嗯,我一直不知道要提供obj文件
A: 这样使得库(obj文件的集合)可以闭源提供给第三方,当然第三方可以逆向分析你的库,但你的库规模比较大的话这个是很难的。
|
|