一般情况下,在任何一个计算机语言中要使用第三方功能时,都需要配置环境,SDL同样如此。
在我一开始学习的时候对环境配置是深恶痛绝的,稍微出错都会影响学习积极性。但不得不承认,环境的配置一般都是第一件要做的事。
一.为什么要进行环境配置?
以c/c++为例,所谓的环境配置就是配置头文件和库文件的目录。因为我们在自己的代码中要使用第三方所提供的API(简单地说,API就是各种函数,比如c/c++的<math.h> 的abs函数),所以需要在编译、链接中要能获取到对应的头文件和库文件的位置。头文件中包含的一般是函数的声明、宏、结构体、类等;而库文件中包含的则是编译后的函数实现的集合。
c/c++程序从编写到执行一般分为以下几个阶段:
图一 来源url
- 预编译:此过程是宏替换,比如#include就是把对应的头文件包含进来、#ifndef是条件判断。
- 编 译:对源代码进行编译,此时会判断用到的函数是否有声明。
- 汇编:把代码转成对应平台下的汇编语言。
- 链 接:把用到的库文件链接到可执行文件中(静态库)。
- 运 行:如果使用到动态库,那么在执行前会尝试链接动态库,只有链接成功才会执行。
如果是在IDE下进行开发的话,通常上面几个阶段都是包含在IDE里面的,比如使用Visual Studio(VS)的话,则只需要点击编译、运行按钮即可。标准库一般都是各个操作系统所提供,而第三方库比如SDL则需要自行配置头文件和库文件的目录,以使得在编译、链接阶段可以查找成功。
库文件又分为静态库和动态库,它们之间的区别仅仅在于链接时间的不同。静态库是在链接阶段链接的,并包含在可执行文件中;动态库则是在运行前才尝试链接的。
动态库复用性高,而且如果该库文件升级之后,则只需要替换相应的库文件而无需对可执行程序进行编译链接。不过静态库链接后仅仅只有一个文件,也得简洁方便。
那么不同的语言是怎么相互调用的呢?比如java就可以调用c/c++的代码。众所周知的是,android开发使用的java语言,不过android游戏开发同样可以用c++开发。
在这之前,先说一说编译型语言和解释型语言的区别。
1.编译型语言
类似于图1,如果该语言有类似于图一所示的编译过程的话,那么一般情况下为编译型语言。
编译型语言是把代码编译链接后为计算机可直接执行的机器码(01代码),比如c/c++就是编译型语言。编译型语言的特点就是运行速度快,但不具备可移植性,即windows下的可执行性程序是无法直接在linux内核下执行的。
2.解释型语言
解释型语言也称为脚本语言,其特点就是边翻译边执行。一般情况下,解释型语言都有一个类似于虚拟机的东西,而代码是在虚拟机里运行的,解释型语言的经典如lua、javascript。
3.其他类型语言
在目前来说,有的语言并不能简单地分为编译型语言或解释型语言,比如java,java是编译成class字节码文件后,再在虚拟机中执行的。
那么java是如何调用c/c++的呢?这就是库文件的优点。前面提到过,库文件是编译后的函数的集合,这也就使得如果可以暴露库文件的接口,理论上在同样的操作系统内,任何一个语言都是可以进行调用的。
二.不同系统下的环境配置
不同操作系统的开发环境配置是类似的,总结起来就是让代码在编译、链接过程中可以找得到对应的头文件和库文件。
对于一般的开发来说,如果只有一个文件的话,那么一个gcc或者g++命令即可(gcc/g++是对源文件进行编译的可执行文件);而如果有多个文件的话,为了方便管理,则需要一个项目管理工具。如果是在windows下的话,Visual Studio(VS)是一个不错的选择;如果是在ubuntu下的话,cmake是个不错的选择。
值得一提的是,VS不仅仅是一个项目管理工具,它的功能及其强大。另外,cmake是跨平台的一个项目管理工具,它是对makefile的封装,cmake通过CMakeFileLists.txt生成makefile文件来编译源文件。而所谓的makefile文件就是编译源文件的规则。
无论是cmake还是makefile,它们的功能都是管理如何编译。
1.Ubuntu环境配置
ubuntu下的环境配置相对比较简单。在ubuntu中,一般可以使用APT(是一个类似于应用市场的软件)进行安装,在安装前可以先搜索一下:
先说明下命名规则:lib是library的简写,表示库;sdl2表示是SDL2库;dev则是development的简写。综上所述,我们要下载的是SDL2开发库,而安装则可以使用下面的命令:
sudo apt install libsdl2-dev
另外,还有几个额外库,也可以先行安装:
sudo apt install libsdl2-dev
sudo apt install libsdl2-image-dev
sudo apt install libsdl2-ttf-dev
sudo apt install libsdl2-mixer-dev
sudo apt install libsdl2-gfx-dev
sudo apt install libsdl2-net-dev
SDL2_image为扩展图像库,用来补充SDL2,因为SDL2库仅仅只能读取BMP格式的图片;SDL2_ttf是字体库;SDL2_mixer是音效库;SDL2_gfx是图片操作库;SDL2_net则是网络库。可根据需要自行安装。后面两个库的使用频率不如前面几个库。
2.Windows环境配置
如果是在windows下进行开发的话,那么推荐Visual Studio(VS)。不得不承认的是,VS这个IDE确实不错,这里我推荐使用Visual Studio 2017 Community,社区版在注册并登陆账号后是可以免费使用的。当然,使用其他的IDE也是可以的,比如Code Block。不过,无论使用什么样的IDE,环境配置大致都相同,都是要确定头文件和库文件的目录。
首先需要去SDL官网去下载对应的开发库,
打开解压后,我们需要的只是是include和lib这两个文件夹,include文件夹中保存的是头文件,而lib文件夹保存的是库文件。
lib中有x86和x64两个文件夹,x86表示32位应用所用的库;而x64则是64位应用所用的库,一般应用默认为32位,所以我们使用的是x86文件夹中的库文件。
接着需要在vs中创建一个空项目,
FirstProejct项目保存在了D盘的VSProject文件夹中,这里推荐以后的项目都创建在此文件夹下,在该文件夹下创建一个common文件夹,把刚下载的include文件夹和lib文件夹放在里面,如下:
像SDL库等通用的库可以为其他项目所共用,因此放在common文件夹下还是可以的。
接下来就是要进行环境配置了,首先右键点击项目:
接着添加头文件目录:
然后添加库文件目录:
还要设置依赖的库:
好了,配置基本完成了,接下来就要编码进行测试了:
#include "SDL.h"
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* win = SDL_CreateWindow("FirstProject", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
bool running = true;
SDL_Event event = {};
while (running)
{
SDL_RenderClear(ren);
//draw here
SDL_RenderPresent(ren);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
running = false;
break;
}
}
}
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
return 0;
}
上面的代码:创建窗口和渲染器,一直循环判断是否有事件,SDL_QUIT表示存在退出事件。
如果此时编译运行的话,应该会出现错误:
这是因为SDL项目还需要动态库 ,所以我们还要在一开始下载的lib文件夹中的x86文件夹中找到SDL2.dll,然后放在Debug文件夹下。
接着编译运行,应该会出现两个窗口,一个SDL窗口,另一个则是控制台窗口。
VS有两个模式,分别是Debug模式和Release模式,顾名思义,Debug模式表示的是调试状态,此时VS会有额外冗余来便于调试;而Release则为发行版本,它会进行优化。这两个模式分别会生成Debug文件夹和Release文件夹。