开发者社区> usher.yue> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

SDL2.0例子代码分析---代码运行平台检测

简介: 简介 SDL2.0例子程序中的 testplatform项目代码分析 ,针对不同的平台 检测字节序 CPU支持的指令集 类型宽度 以及断言 代码+注释 #include #include "SDL.
+关注继续查看

简介

SDL2.0例子程序中的 testplatform项目代码分析 ,针对不同的平台 检测字节序 CPU支持的指令集 类型宽度 以及断言

代码+注释

#include <stdio.h>

#include "SDL.h"
#include "SDL_endian.h"
#include "SDL_cpuinfo.h"
#include "SDL_assert.h"

/*
 *  该例子代码检测运行平台
 */
//判断变量占用字节数 是否等于 hardcodetype
static int
badsize(size_t sizeoftype, size_t hardcodetype)
{
	return sizeoftype != hardcodetype;
}


//检测系统是否出现错误类型   貌似用处不大这段坑爹代码 
//如果平台类型错误 返回1 否则返回  0
int
TestTypes(SDL_bool verbose)
{
	int error = 0;

	//如果Uint8占用一个字节
	if (badsize(sizeof(Uint8), 1))
	{
		//如果Uint8不等于1那么输出 实际占用尺寸 
		if (verbose)
			SDL_Log("sizeof(Uint8) != 1, instead = %u\n",
			(unsigned int)sizeof(Uint8));
		//错误次数++
		++error;
	}
	//如如下类似 上述 
	if (badsize(sizeof(Uint16), 2)) {
		if (verbose)
			SDL_Log("sizeof(Uint16) != 2, instead = %u\n",
			(unsigned int)sizeof(Uint16));
		++error;
	}
	if (badsize(sizeof(Uint32), 4)) {
		if (verbose)
			SDL_Log("sizeof(Uint32) != 4, instead = %u\n",
			(unsigned int)sizeof(Uint32));
		++error;
	}
	if (badsize(sizeof(Uint64), 8)) {
		if (verbose)
			SDL_Log("sizeof(Uint64) != 8, instead = %u\n",
			(unsigned int)sizeof(Uint64));
		++error;
	}
	if (verbose && !error)
		SDL_Log("All data types are the expected size.\n");

	return (error ? 1 : 0);
}

//测试尾数  也就是机器的字节序  
//windows默认是小端模式 
//也就是 低位先存 原因是 堆栈是 由高地址向低地址扩展
int
TestEndian(SDL_bool verbose)
{
	int error = 0;
	Uint16 value = 0x1234;
	int real_byteorder;
	Uint16 value16 = 0xCDAB;
	Uint16 swapped16 = 0xABCD;
	Uint32 value32 = 0xEFBEADDE;
	Uint32 swapped32 = 0xDEADBEEF;
	Uint64 value64, swapped64;

   //定义64位置 也就是 0x00000000EFBEADDE
	value64 = 0xEFBEADDE;
	//右移动32位  也就是四个字节
	value64 <<= 32;
	//将低位置为0xCDAB3412
	value64 |= 0xCDAB3412; 
	//如下操作和value64雷同 
	swapped64 = 0x1234ABCD;
	swapped64 <<= 32;
	swapped64 |= 0xDEADBEEF;
	//打印机器字节序 是大端模式还是小端模式 
	if (verbose) {
		SDL_Log("Detected a %s endian machine.\n",
			(SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big");
	}
	//我们自己判断字节序 将value转换为 char类型之后 由于数据丢失 变成了0x34 在windows下低位先存 
	//所以 左移4位后变成了0x3了  也就是小端口模式
	if ((*((char *)&value) >> 4) == 0x1) {
		real_byteorder = SDL_BIG_ENDIAN;
	}
	else {
		real_byteorder = SDL_LIL_ENDIAN;
	}
	//如果我们分析的 真正的字节序不等于 SDL给出的字节序 那么 输出真正的字节序 error++
	if (real_byteorder != SDL_BYTEORDER) {
		if (verbose) {
			SDL_Log("Actually a %s endian machine!\n",
				(real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big");
		}
		++error;
	}
	//交换字节序 输出 
	if (verbose) {
		SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16,
			SDL_Swap16(value16));
	}
	//如果交换后的值不等于 0xABCD 
	if (SDL_Swap16(value16) != swapped16) {
		if (verbose) {
			SDL_Log("16 bit value swapped incorrectly!\n");
		}
		++error;
	}
	//交换32位高度字节序 
	if (verbose) {
		SDL_Log("Value 32 = 0x%X, swapped = 0x%X\n", value32,
			SDL_Swap32(value32));
	}
	if (SDL_Swap32(value32) != swapped32) {
		if (verbose) {
			SDL_Log("32 bit value swapped incorrectly!\n");
		}
		++error;
	}
	if (verbose) {  
		//如果是微软的编译器 也就是VC下 打印出64位的交换字节序之后的值
#ifdef _MSC_VER
		SDL_Log("Value 64 = 0x%I64X, swapped = 0x%I64X\n", value64,
			SDL_Swap64(value64));
#else  
		//如果是其他编译器 那么  64位置 ULONG 就需要定义为 unsigned long long 来代表 64位无符号 Integer
		SDL_Log("Value 64 = 0x%llX, swapped = 0x%llX\n",
			(unsigned long long) value64,
			(unsigned long long) SDL_Swap64(value64));
#endif
	}
	//判断交换后的值是否等于 0x1234ABCDDEADBEEF;
	if (SDL_Swap64(value64) != swapped64) {
		if (verbose) {
			SDL_Log("64 bit value swapped incorrectly!\n");
		}
		++error;
	}
	//返回错误状态
	return (error ? 1 : 0);
}


//检测CPU 的特性
int
TestCPUInfo(SDL_bool verbose)
{  
	if (verbose) {  
		//打印CPU数量
		SDL_Log("CPU count: %d\n", SDL_GetCPUCount()); 
		//获取CPU Cache LIne的大小 即CPU 一次从主存Copy的内存大小
		SDL_Log("CPU cache line size: %d\n", SDL_GetCPUCacheLineSize());
        //CPU是否支持RDTSC指令 读取时间标签计数器
		SDL_Log("RDTSC %s\n", SDL_HasRDTSC() ? "detected" : "not detected");
		///cpu 是否支持 Altivec  AltiVec提供了32个128比特向量暂存器,与之相比,SSE和SSE2只提供了8个
		SDL_Log("AltiVec %s\n", SDL_HasAltiVec() ? "detected" : "not detected");
		//cpu是否支持 MMX指令 
		SDL_Log("MMX %s\n", SDL_HasMMX() ? "detected" : "not detected"); 
		//CPU是否支持SIMD , 由AMD开发的一套SIMD多媒体指令集,支持单精度浮点数的矢量运算,用于增强x86架构的计算机在三维图像处理上的性能
		SDL_Log("3DNow! %s\n", SDL_Has3DNow() ? "detected" : "not detected"); 
		//cpu是否支持SSE
		SDL_Log("SSE %s\n", SDL_HasSSE() ? "detected" : "not detected");
		//SSE2是否支持 如下都是判断CPU是否支持一下加速指令集 
		SDL_Log("SSE2 %s\n", SDL_HasSSE2() ? "detected" : "not detected");
		SDL_Log("SSE3 %s\n", SDL_HasSSE3() ? "detected" : "not detected");
		SDL_Log("SSE4.1 %s\n", SDL_HasSSE41() ? "detected" : "not detected");
		SDL_Log("SSE4.2 %s\n", SDL_HasSSE42() ? "detected" : "not detected");
		SDL_Log("AVX %s\n", SDL_HasAVX() ? "detected" : "not detected");
		//获取系统RAM大小 也就是内存大小
		SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
	}
	return (0);
}

int
TestAssertions(SDL_bool verbose)
{  
	//sdl断言
	SDL_assert(0);
	SDL_assert_release(1);
	SDL_assert_paranoid(1);
	SDL_assert(0 || 1);
	SDL_assert_release(0 || 1);
	SDL_assert_paranoid(0 || 1);

#if 0   /* enable this to test assertion failures. */
	SDL_assert_release(1 == 2);
	SDL_assert_release(5 < 4);
	SDL_assert_release(0 && "This is a test");
#endif

	{  
		//获取所有的断言 链表  在调用SDL_GetAssertionReport 之前 
		/************************************************************************/
/*
			typedef struct SDL_assert_data
			{
			int always_ignore;
			unsigned int trigger_count;
			const char *condition;
			const char *filename;
			int linenum;
			const char *function;
			const struct SDL_assert_data *next;
			} SDL_assert_data;                                                                     */
		/************************************************************************/
		const SDL_assert_data *item = SDL_GetAssertionReport(); 
		//我们发现就是取出所有的 断言结果 输出
		while (item) {
			SDL_Log("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
				item->condition, item->function, item->filename,
				item->linenum, item->trigger_count,
				item->always_ignore ? "yes" : "no");
			item = item->next;
		}
	}
	return (0);
}

int
main(int argc, char *argv[])
{
	SDL_bool verbose = SDL_TRUE;
	int status = 0;

	/* 设置特定日志的优先级 这里是应用程序日志  */
	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
	//如果参数1= -q 那么设置 verbose=faslse
	if (argv[1] && (SDL_strcmp(argv[1], "-q") == 0)) {
		verbose = SDL_TRUE;
	}
	if (verbose) {
		SDL_Log("This system is running %s\n", SDL_GetPlatform());
	}
	//测试变量尺寸
	status += TestTypes(verbose);
	//测试尾数  也就是测试机器的字节序
	status += TestEndian(verbose);
	//测试CPU信息
	status += TestCPUInfo(verbose);
	//测试断言
	status += TestAssertions(verbose);

	return status;
}
<img src="http://img.blog.csdn.net/20141220011403769?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXVlNzYwMzgzNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【CSAPP】x86-64的机器代码和原始的C代码差别巨大,一些常在C语言中隐藏的处理器状态
【CSAPP】x86-64的机器代码和原始的C代码差别巨大,一些常在C语言中隐藏的处理器状态
0 0
Hello World细节-自动配置|学习笔记
快速学习Hello World细节-自动配置
0 0
在C++学习的过程中如何使每个 .cpp单独运行
在C++学习的过程中如何使每个 .cpp单独运行
0 0
不要再用main方法测试代码性能了,用这款JDK自带工具
不要再用main方法测试代码性能了,用这款JDK自带工具
0 0
Python 技术篇-在cmd命令提示行里模拟动态下载进度条实例演示,cmd清除日志、打印动态内容方法
Python 技术篇-在cmd命令提示行里模拟动态下载进度条实例演示,cmd清除日志、打印动态内容方法
0 0
使用LLDB脚本简化打印复杂数据的操作
上次提到用了LLDB脚本来扩展一些功能。 这次是简化打印复杂数据的操作。   不知道大家都没有遇到过在gdb和lldb里输出一个类时困扰,常常要一个个属性展开下去,或者调用提供函数来检查。
600 0
VC最简版图片打印程序
自认为注释已经很详细了,没有什么可说的,以后再用的时候如果还有哪不明白的就当长教训了 BOOL CMYDlg::PrintPic(CString strFileName,int iCopies,CString strPr...
571 0
[记]一个逐步“优化”的范例程序
一个逐步“优化”的范例程序 引言 本文是《Object-Oriented Analysis and Design》一书第一章和第五章的读书笔记。我对书中提供的一个范例程序进行了总结和整理,通过逐步优化这个乐器管理的范例程序,分析了进行程序设计时需要注意到的一些问题。
492 0
+关注
usher.yue
算法相关技术专家
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Flash Player最新安全特性分析 及绕过思路
立即下载
Flash Player最新安全特性分析及绕过思路
立即下载
《0代码搭应用》
立即下载