Linux 下C++开发入门

Linux 下C++开发入门指南

                                Alan Luo 2017-01-13

本文目的是针对将熟悉C/C++语法,如何在Linux下进行的C/C++开发的入门指南。Linux下的开发和在Windows下的开发类似,主要区别点在于操作系统不同,开发工具,开发API,编译调试方法不一样,故主要将针对这些不同点进行阐述,使在Windows开发的程序员能够入门Linux下C++ 开发的行列中。

一,涉及技术以及开发工具

1,工具

1.1 Linux环境

首先,你得有一台Linux机器,目前的开发环境是10.88.115.114,机器需要安装g++/gcc编译器环境,文本编辑器,如vim等,一般安装操作系统会安装好,如果系统没有需要自行安装。

输入g++ -v 查看本机是否安装g++环境

 

安装方式有两种,YUM安装和源代码安装方式。推荐使用YUM安装方式。

Yum安装可以自动解决库依赖问题,所以推荐使用。YUM安装g++:

yum list gcc-c++

yum install gcc-c++.i686

自动安装即可。

 

另外开发过程中,需要调试,故Linux机器也需要安装gdb调试工具。

Gdb安装方式类似:

yum install gdb

1.2 Windows工具

Linux下的开发一般不是直接在Linux下进行开发,当然如何愿意也是可以的,可以直接使用VIM进行开发。但是需要很长的时间熟练使用VIM的快捷键,对于入门开发来说过于困难,故直接在Windows下开发者居多。在Windows下开发Linux下应用主要使用的工具如下:

(1)Xshell,用于连接Linux主机,可以使用free for school版本,百度一下安装即可

 

最后可以配置成如下简洁界面,让人感觉轻松大气。

Alt+Ctrl+F组合键可以弹出文件传输界面,开发和升级的时候,在Linux和Windows之间进行文件传输。如图所示。

 

(2)Code::Blocks

在Windows下将源代码从linux下拉来后,需要在本地进行开发。可以直接使用文本编辑器开发,但是缺少关键字高亮,函数跳转等功能,开发起来比较困难。故需要使用到IDE工具。下面介绍3款工具。

第一款,Code::Blocks,这一款比较推荐,在Windows和Linux下都有版本。新建工程,File->New->Project,将代码加入工程后即可进行开发,可以关键字高亮,函数跳转,函数引用列表等功能。主要缺点是开发好的代码需要上传到Linux开发机器上进行编译调试。

 

第二款,Source Insight

Source Insight使用较广,使用方式和Code::Blocks基本一致,只是快捷键不一致。缺点同样是需要把文件上传后编译开发。

 

第三款,Eclipse+RSE插件

Eclipse安装Remote System Explorer插件后,可以直接连上linux的机器,对机器上的代码进行直接编辑开发,此种开发的模式优点是不需要对代码文件上传,缺点是对函数跳转,查找等功能很欠缺,基本上相当于文件编辑模式。

 

上面三种IDE都可以进行Linux下C++的开发,但是编译链接调试依然是在Linux环境下进行。所以可以根据各自的优缺点进行选择。

1.3 Linux下技术

Linux下开发的基本技能要求如下:

熟悉Linux下基本命令:

cp /rm/ find/cd/ll/mkdir 等等

熟悉Makefile文件编写

开源库搜索与安装yum

调试工具gdb的使用

Linux API

下面将详细讲解这些技术的使用。

二,Demo开发及发布

至此,Linux下环境的开发工具齐全了,下面开始从头开始搭建工程。

(1)创建工程

登录开发机器115.114,新建目录Demo,进入该目录:

cd /home/

mkdir Demo

cd Demo

 

(2)新建文件

新建3个文件

 

分别输入如下内容

1. print.h

#include<stdio.h>

void printHello();

2. print.c

#include"print.h"

void printHello(){

  printf("Hello, world\n");

 }

3. main.c

#include "print.h"

int main(void){

 printHello();

 return 0;

}

(3)创建MakeFile文件

helloworld:main.o print.o

    g++ -o helloworld main.o print.o

main.o:main.cprint.h

    g++ -c main.c

print.o:print.cprint.h

    g++ -c print.c

clean: rmhelloworld main.o print.o

 

其中makefile的撰写是基于规则的,当然这个规则也是很简单的,就是:

target (生成的对象): prerequisites(生成对象的依赖条件)

  command  //任意的shell 命令                                        

如helloworld:main.o print.o

g++ -o helloworld main.o print.o

需要生成可执行文件helloworld,则需要依赖main.o print.o 文件,即使用g++ -o helloword main.o print.o生成helloword,

其中-o 生成的可执行文件名称,main.o print.o是已经生成好的两个文件对象。

接下来,

main.o:main.cprint.h

g++ -c main.c

即main.o的生成由main.c和 print.h编译得来,即执行g++ -c main.c命令生成。以此类推。当然如果在项目源文件和头文件都比较多的情况下,采用该种编写方式会比较繁琐且容易出错,故可以使用Makefile中的一些函数进行自动编译。可参考Makefile的相关教程。

其中clean的命令是删除文件helloworld main.o print.o,写好此文件后,make clean 可以实现将生成的文件删除从而可以再次进行编译。

(4)编译执行

发好了源文件以及MakeFile文件后,接下来可以进行编译运行。在当前目录先执行make命令;

 

可以看到Makefile中的命令都已经执行,查看当前目录ls;

 

可以看到生成了可执行文件helloworld和中间过程文件main.o,print.o。

输入命令./helloworld后可以看到界面打印出了hello world字样。

 

 

三,调试测试开发

程序开发必定需要进行调试开发。在Linux下开发调试主要依靠GDB工具。

首先,编译的时候需要在编译命令中加入-g选项,这样保证调试的时候可以打印出源代码。

添加-g,修改Makefile文件之后,重新编译make ,可以看到编译命令中多出了-g。

 

 

进入调试模式,gdb helloworld

 

gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help <class> 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help <command>来查看命令的帮助。

l+函数名称可以查看函数源码

 

 

设置断点,输入命令

b 3

 

则再文件main的第三行设置了断点。

如果需要设置其他文件中的函数断点,可以如图设置,即文件名加函数名称,或者函数行数即可

 

Info break 命令即可查看当前设置的所有断点。

 

输入命令r,调试运行程序开始。程序卡在第一个断点的位置上。此时输入命令 s,即可进入该函数里面进行调试,输入命令l即可查看当前函数的源代码;

 

输入命令n可以进行单步执行;

 

输入 p+变量名 可以打印当前变量的值;

 

输入命令q退出调试;

 

Gdb 命令丰富多彩,目前介绍的只是最基本的命令,但是针对一般的调试已经足够,需要用户自己不断的学习发掘才能最大限度的使用gdb的好处。  

四,高阶Demo开发

接下来介绍一个进阶版开发教程。主要从头开始搭建一个包含一些功能模块的项目。本Demo主要包括日志打印,配置文件读取,UDP端口监听,开启线程等功能。

(1)新建工程目录

mkdir HighDemo

 

 

然后创建cpp,.h文件

 

其中base64主要用来进行base64编码解码,comm_codec主要用来通用的解析XML,格式转换等函数集合,config主要用来加载配置文件config.xml,LogClinet主要用来打印日志文件,strtok_r主要用来字符串切割,其中NetFrame是包含main方法的主线程文件。创建完了CPP和头文件之后,将创建Makefile文件。

(2)Makefile文件编写

进阶版的Makefile,先从两个函数可以讲起。函数Wildcard和函数patsubst。

“$(wildcard *.cpp)”来获取工作目录下的所有的.cpp文件列表

以使用“$(patsubst %.cpp,%.o,$(wildcard *.cpp))”,首先使用“wildcard”函数获取工作目录下的.cpp文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。

三个变量分别是$@,$^,$<代表的意义分别是:

$@--目标文件,

$^--所有的依赖文件,

$<--第一个依赖文件。

所以本项目的Makefile文件写成如下

TARGET=NetFrame

CC=g++

INCLUDES+=-I./include   -I/usr/local/src/oracle/10g/rdbms/public-I/usr/include/libxml2 -I/usr/local/ssl/include -I/usr/local/include

LIB=-lstdc++-lpthread -lrt -L/usr/local/src/oracle/10g/lib -lclntsh   -L/usr/lib64 -lxml2-L/usr/local/ssl/lib -lcrypto

OBJS:=$(patsubst %.cpp,%.o,$(wildcard *.cpp))

 

$(TARGET):${OBJS}

   $(CC) $^ $(LIB)  -o $@

 

.cpp.o:

   $(CC) $(FLAGS) $(INCLUDES)  -o $@ -c $<

 

clean:

   rm-rf $(TARGET)

   rm-f $(OBJS)

输入命令

make

 

则生成可执行文件NetFrame

INCLUDES和LIB主要是使用到的库头文件和动态库或者静态库文件的路径,包含进来即可。如果使用了新的开源库,则需要安装以及查找对应的库路径添加进来。

如需要使用libcurl库,则yum search curl

找到curl-devel.x86_64,再yum install curl-devel.x86_64 安装即可

 

之后如果你不确定动态库被安装到哪里去了,可以输入如下命令:

find / -name libcurl*,如图

 

(3)Main文件编写

编写NetFrame.cpp文件。

首先导入相关头文件,其中<>表示引用的是编译器的类库路径里面的头文件" "引用的是你程序目录的相对路径中的头文件,设置一下常量(最好放在头文件里)。

 

之后定义Main函数,调用各个模块的函数接口实现对应的功能,如调用日志函数打印日志,调用配置文件解析配置,获取配置文件中的参数功能。

 

另外开启一条线程,进行UDP的监听操作,开启的端口和IP从配置文件中读取。

 

该线程实现的功能也很简单,用户发送指定格式的UDP包,系统收到报文后,解析报文内容进行返回数据或者重新加载配置文件等等。

 

输入命令./NerFrame命令启动进程。

 

另开一个窗口,输入测试数据

echo "task=reload&msg=pleasereload"|nc -u 127.0.0.1 9999

 

可以看到返回了msg里面的内容

服务端重新加载了配置文件。

 

 

至此,高阶版Linux下C/C++开发指南介绍完毕,从头开始实践可以把一个熟悉C/C++语法的程序员带入Linux的世界中。

另外,由于是在Linux下开发,所以需要熟悉Linux的系统函数,这些系统函数是在程序中大量使用到,如open,close,recvfrom等等,推荐一本书《UNIX操作系统设计》,可以学习很多操作系统的API,对于程序开发有很大的帮助。另外如果对Linux内核有兴趣的可以学习《深入理解Linux内核》

Linux环境下的C++开发

因为想要把程序从Windows平台移植到Linux平台,故写了此系列文章,以方便以后自己和大家,少走弯路

整个环境采用CentOS7+QtCreator+cmake+gcc的形式

1、从https://www.centos.org/download/上下载CentOS镜像,我选的是DVD ISO版本。然后选择一款虚拟机,我使用Virtual Box,这里记住最好选择最新的虚拟机版本,我就是使用老版的虚拟机,导致虚拟机增强插件安装失败。

选择新建虚拟机,类型和版本如下,CentOS是Red Hat的衍生版本。

后面的选项按自己的习惯设置。设置好后,把CentOS的镜像设置到虚拟机的DVD光驱里,启动虚拟机

启动到下面界面后,直接选择第一个选项“Install CentOS 7”,这样快些,因为不用检测镜像完整性。

选择安装界面语言,默认选择英文。我这里考虑到兼容性,所以安装界面和操作系统语言我都是选择的英文

安装选项

Date & Time,选择中国上海。

Language support,我们会使用中文,所以最好添加中文支持

softwave selection,因为我初次使用Linux,所以选择了带桌面,但不管是选择哪个Base Environment,右边的Development Tools最好选中,会省去你安装gcc和内核源码等软件的时间。

installation destionation,选择你想安装的位置,我这就一个虚拟盘

然后就可以点击安装了,点击安装后,会出现安装界面,顺便让你设置root账户密码和是否添加新用户,这里按自己习惯设置

等待一段时间后系统就安装好了

1、安装cmake(以cmake-3.12.0.tar.gz源码安装为例)

先去官网https://cmake.org/download/上下载cmake源码。下载后解压编译,gmake install需要root权限

tar zxvf cmake-3.12.0.tar.gz

cd cmake-3.12.0

./bootstrap

gmake

gmake install

2、安装qtCtreator

http://download.qt.io/official_releases/qtcreator/下载需要的qtCreator版本,然后运行安装文件即可

3、创建C++项目

运行qtCreator,菜单的“File”->“New File Or Project”

右边Projects选择Non-Qt Project,中间选择Plain C++ Application,然后点击右下角的Choose

然后选择项目的存放位置

编译方式,这里我们选择CMake

然后选择部署平台,如果之前安装好了gcc、gdb、cmake,这里会自动出现一个默认的kit,如果没有自动识别出来或提示识别失败,可以在菜单的“Tools”->“Options”->“Kits”中设置。

版本管理,按自己的习惯选择,点击“Filish”就创建了C++项目


 

qtCreator对cmake支持还不是那么好,在项目中无法通过右键添加源文件,只有在CMakeList.txt中显示添加的文件才会在项目列表中显示出来。在CMakeList.txt中添加如下代码,就能把项目下的所有.h和.cpp的文件都在左边项目列表中显示出来

file(GLOB files_list ./*.cpp ./*.h)
add_custom_target(files_list SOURCES ${files_list})

如果需要对g++添加自定义参数,配置如下

#g++编译参数
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pthread -m64 -std=c++11")

 

添加第三方库头文件目录和库目录配置如下

#第三方库库文件目录
link_directories("/home/user/boost_1_67_0/lib")
#第三方库头文件目录
include_directories("/home/user/libev-4.24" "/home/user/boost_1_67_0")

 

配置生成执行程序

#输出项目名称
project(app)
#编译项目所需源码
set(SRC_APP "aaa.cpp" "bbb.h")
add_executable(${PROJECT_NAME} "main.cpp" ${SRC_APP})

 

配置生成动态库

#输出项目名称
project(module_abc)
#编译项目所需源码,.表示CMakeList.txt所在文件夹下所有源文件
AUX_SOURCE_DIRECTORY(. SRC_ABC)
#编译成动态库
add_library(${PROJECT_NAME} SHARED ${SRC_ABC})
#动态库按C语言接口导出
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)

 

添加第三方依赖库配置如下(以libev库为例,${PROJECT_NAME}是之前定义的输出程序名称)

target_link_libraries (${PROJECT_NAME}  ev)

 

添加子项目,module_abc指当前文件夹下的module_abc文件夹

add_subdirectory(module_abc)

 

VS编译utf8源码时的问题

在VS里编译utf8格式的源代码时,有时会出现以下错误:

E:\Projects\back_mdfactory\src\service_context.cpp(33): error C2001: 常量中有换行符
E:\Projects\back_mdfactory\src\service_context.cpp(33): fatal error C1057: 宏扩展中遇到意外的文件结束

原因是VS默认使用带BOM的UTF8格式源码编译,遇到不带BOM的UTF8源码时,会当成ANSI格式源码,导致出现一些莫名奇妙的错误。方法有几种:

1、将源码从不带BOM的UTF8改为带BOM的UTF8源码,这个会对跨平台开发有影响,因为Linux默认是不带BOM源码。

2、在源码的中文字符串后面加一个空格或是其他字符,这个会强行改变源码内容

3、修改VS工程属性,C/C++ -> 命令行 的其他选项里,增加/utf8,这个最合适,但貌似要求VS2015 Update 1以上版本。

C++中的.和::和:和->的区别

  在学习C++的过程中我们经常会用到.和::和:和->,在此整理一下这些常用符号的区别。 

    1、A.B则A为对象或者结构体;

    2、A->B则A为指针,->是成员提取,A->B是提取A中的成员B,A只能是指向类、结构、联合的指针;

    3、::是作用域运算符,A::B表示作用域A中的名称B,A可以是名字空间、类、结构;

    4、:一般用来表示继承;

Linux下批量转换windows格式“\r\n“转为“\n“

Linux下,查找当前目录所有文件并将其中\r格式取掉。方法仅供参考,谨慎使用或使用前备份。

find . -type f -print0 | xargs -0 sed -i "s/\r//g"
#xargs命令中-0用于去除空格内容,通过null分隔参数

本文源站链接:LinuxShell基础命令

linux批量去bom命令

grep -r -I -l $’^\xef\xbb\xbf’ ./*|xargs -i sed -i ‘1 s/^\xef\xbb\xbf//’ {}
在linux上面运行,将上面的./*换成你的目录即可。

 

linux实现时间同步有哪几种方法

Linux实现时间同步的方法的有两种,分别是:1、使用ntpdate从时间服务器来更新时间,不需要自己做任何配置;2、使用ntp来搭建自己的时间服务器。

【推荐课程:Linux系统

由于硬件的原因,机器或多或少的跟标准时间对不上,误差几秒到几分钟不等。对于服务器来说时间不准会有很多麻烦。例如支付的时候,无法下单,游戏无法登录等。接下来将在文章中为大家分享Linux系统中如何实现时间同步,希望对大家有所帮助

方法一:用ntpdate从时间服务器更新时间

如果linux系统没有ntpdate这个命令,可以输入以下代码进行安装

1

yum install ntp

安装完了之后,你不要做什么配置,也不需要,直接测试一下

1

2

3

4

5

vi /etc/ntp.conf

add below:

server 1.cn.pool.ntp.org

server 3.asia.pool.ntp.org

server 2.asia.pool.ntp.org

restart service and sync the time

1

2

[root@localhost ~]# ntpdate time.nist.gov 

22 Oct 21:11:43 ntpdate[5014]: adjust time server 207.200.81.113 offset -0.018788 sec

如果显示上面的内容说明同步成功了,然后在crontab里面加上以下内容。

1

*/10 * * * * ntpdate time.nist.gov   #域名或IP

每隔十分钟同步一次。推荐几个时间服务器。

time.nist.gov

time.nuri.net

0.asia.pool.ntp.org

1.asia.pool.ntp.org

2.asia.pool.ntp.org

3.asia.pool.ntp.org

方法二、用ntp搭建自己的时间服务器

上面是利用别人的时间服务器来同步时间,这些时间服务器都是比较权威的。当我们自己搭建时间服务器就不用crontab来定时去跑。

1、安装时间服务器ntp

1

yum install ntp

2、配置ntp

1

2

3

4

5

6

7

8

9

10

11

12

[root@localhost ~]# cat /etc/ntp.conf |awk '{if($0 !~ /^$/ && $0 !~ /^#/) {print $0}}' 

restrict default ignore   //默认不允许修改或者查询ntp,并且不接收特殊封包 

restrict 127.0.0.1        //给于本机所有权限 

restrict 192.168.1.0 mask 255.255.255.0 notrap nomodify  //给于局域网机的机器有同步时间的权限 

server time.nist.gov prefer      //设置时间服务器,加prefer表示优先 

server 0.asia.pool.ntp.org 

server 1.asia.pool.ntp.org 

server 2.asia.pool.ntp.org 

server  127.127.1.0     # local clock 

fudge   127.127.1.0 stratum 10 

driftfile /var/lib/ntp/drift 

keys /etc/ntp/keys

3、启动 ntp

1

[root@localhost ~]# /etc/init.d/ntpd start

4、查看并测试

1

2

3

4

5

6

7

8

9

10

11

12

13

[root@localhost ~]# netstat -upnl |grep ntpd   //查看时程   

[root@localhost ~]# ntpq -pn    //查看同步的服务器IP  

remote           refid      st t when poll reach   delay   offset  jitter 

==============================================================================  

50.77.217.185   .INIT.          16 u    -   64    0    0.000    0.000   0.000  

202.90.158.4    .INIT.          16 u    -   64    0    0.000    0.000   0.000  

202.71.100.89   .INIT.          16 u    -   64    0    0.000    0.000   0.000  

202.134.1.10    .INIT.          16 u    -   64    0    0.000    0.000   0.000 

*127.127.1.0     .LOCL.          10 l   18   64  377    0.000    0.000   0.001   

[root@localhost ~]# ntpstat   //同步的结果 

synchronised to local net at stratum 11  

time correct to within 12 ms  

polling server every 512 s

remote:即NTP主机的IP或主机名称。注意最左边的符号,如果由“+”则代表目前正在作用钟的上层NTP,如果是“*”则表示也有连上线,不过是作为次要联机的NTP主机。

  • refid:参考的上一层NTP主机的地址

  • st:即stratum阶层

  • when:几秒前曾做过时间同步更新的操作

  • poll:下次更新在几秒之后

  • reach:已经向上层NTP服务器要求更新的次数

  • delay:网络传输过程钟延迟的时间

  • offset:时间补偿的结果

  • jitter:Linux系统时间与BIOS硬件时间的差异时间

推荐第一种方法,虽然搭建个时间服务器,比较简单的,但是我觉得没有这个必要。如果用别人的时间服务器,每隔10分钟同步一次,可以精确到毫秒。

https://m.php.cn/article/417290.html

 

posted @ 2021-01-29 17:04  CharyGao  阅读(3900)  评论(0编辑  收藏  举报