【C】C语言机制熟悉——头文件
国庆前,接到工作安排,未来会维护一些新的代码,其中包括 C++
项目,大概看了一下,核心内容分为两部分:
- 调用第三方动态库
dll
,用以采集数据 - 利用
zeromq
与其他服务程序做通信以传递数据
看了一下利用 zeromq
通信的代码部分,走的是 C
语言的库, C++
本来就几乎完全兼容 C
语言,即 C
语言代码可以不加修改的用于 C++
。接下来就先熟悉一下 C
语言头文件的机制。
1. 头文件
为自己的代码添加头文件,就有点像go与C#中接口一样,有约束的作用,也方便了调用。
#include "zmq.h"
ZMQ_EXPORT void *zmq_socket (void *, int type);
ZMQ_EXPORT int zmq_close (void *s);
//omit other code...
2. 链接
C/C++
会经历预处理-编译-汇编处理变成目标文件,目标文件中包括了机器语言指令,虽然目标文件包含机器语言指令,但它并不是一个完整的程序。因为任何一门发展至今的编程语言,都不再可能从0开始写代码,都会调用语言平台提供的代码库(运行时库、标准库),当然也可能是动态库或者静态库,这个我们以后再表。
当编译器生成目标文件时,它并不包括代码中使用到的任何运行时库的机器代码。链接器会将目标文件与必需的运行时库例程相结合。链接器完成,则会创建可执行文件。
比如标准输入输出:
#include <stdio.h>
3. 第三方库
除了运行时库,还有第三方库,就拿 zeromq
官方C语言代码为例:
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
printf ("Connecting to hello world server…\n");
void *context = zmq_ctx_new ();
void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");
int request_nbr;
for (request_nbr = 0; request_nbr != 10; request_nbr++) {
char buffer [10];
printf ("Sending Hello %d…\n", request_nbr);
zmq_send (requester, "Hello", 5, 0);
zmq_recv (requester, buffer, 10, 0);
printf ("Received World %d\n", request_nbr);
}
zmq_close (requester);
zmq_ctx_destroy (context);
return 0;
}
尖括号只在系统默认目录或者尖括号内的路径查找,通常用于引用标准库中自带的头文件,这里 zeromq
能够使用尖括号 <zmq.h>
,是因为官方默认你会安装至默认目录下,实际上在mac的M1版,路径也有所不同,前面博文提到过这个问题:
brew install zmq
# /opt/homebrew/Cellar/zeromq
好了,如果是上面的代码,在mac下,代码是编译不通过的,因为找不到 zmq.h
头文件,这里有两种方法可以解决这种问题:
方法一:自己补充一个头文件
编译器首先在程序源文件所在目录查找,如果未找到,则去系统默认目录查找,通常用于引用用户自定义的头文件。这种情况如果是用 vscode
做开发,又想利用智能提示和转到定义等操作记得修改配置。
这时,引用头文件时,就要使用双引号:
#include "zmq.h"
方法二:修改编译器加载头文件路径配置
如果开发环境是visual studio,工程—属性—c/c++—常规—附加包含目录:加上头文件存放的目录。
如果开发环境是mac,zeromq安装后,是自带头文件的,编译器是gcc,请修改gcc配置即可。
- 原文作者:Garfield
- 原文链接:http://www.randyfield.cn/post/2021-10-17-clang-quick-review/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。