2010年9月26日
恩恩,这个小玩具(龙之谷加点模拟器)一个月前就开始做了,因为对GTK不熟悉,所以中间拖了很久,现在基本功能已经实现,界面如下,有不少按钮以及全部菜单都是假的,无所谓,基本的功能已经OK了,下一步应该会加上视频演示吧。。恩,自我感觉良好。(今天真开心。。啦啦啦)
posted @
2010-09-26 01:44 RayRiver 阅读(303) |
评论 (0) |
编辑 收藏
2010年5月18日
今天在把linux下做的ipmsg移植到windows过程中,因为包含了一个开源库SimpleSocket,而这个库又引用了winsock2,没太注意就写下了下面的makefile:
g++ -o tt tt.o
-lws2_32 -lclsocketd
结果报出了N多丑陋的undefined reference..之后尝试将-lws2_32和-lclsocketd交换位置后,编译通过。
上网查了下,发现gcc编译时依赖库的顺序是很重要的。比如说,liba.a依赖于libb.a,则必须写成-la -lb,似乎感觉这种顺序很奇怪。另外参考网上
http://www.cppblog.com/findingworld/archive/2008/11/09/66408.html的内容,在库比较多依赖关系比较复杂或者相互依赖或者自己不清楚的情况下,可以采取下面2种办法:
1、-la -lb -la,丑陋,但是有效。
2、gcc有这样的选项,-Xlinker,写成如下格式可以强制gcc重复查找依赖库:
g++ -o tt tt.o -Xlinker "-("
-lws2_32 -lclsocketd "-)"
这样在括号中的库的依赖关系就不需要你操心啦,虽然会延长链接时间。不过本人在实际使用过程中,g++认不出"-)",不加也可以链接成功。
posted @
2010-05-18 02:01 RayRiver 阅读(7406) |
评论 (1) |
编辑 收藏
2010年5月15日
为了方便调试,需要在VS中为GUI程序添加console窗口。
项目 -> 属性 -> 配置属性 -> 生成事件 -> 生成后事件 -> 命令行:
editbin /SUBSYSTEM:CONSOLE $(OUTDIR)\ipmsg.exe
ipmsg.exe改为可执行代码的文件名。
posted @
2010-05-15 22:31 RayRiver 阅读(680) |
评论 (0) |
编辑 收藏
2010年4月28日
SDL里将所有stdout和stderr重定向到了stdout.txt和stderr.txt文件中,在学习SDL的过程中,每次要打开一个文本文件看日志很麻烦。之前也遇到这个问题,没有解决,这次特意上网找了下,终于得以解决。
参考解决方案地址:
http://www.gamedev.net/community/forums/topic.asp?topic_id=371770下面说下解决办法。
SDL源码src\main\win32目录下有个SDL_win32_main.c这个文件,里面处理了输出流的重定向。有这么几句:
#ifndef NO_STDIO_REDIRECT
else {
redirect_output();
}
#endif
可以看到NO_STDIO_REDIRECT这么一个条件,因为这是在编译过程中选择的,而SDL代码里并没有关于NO_STDIO_REDIRECT的定义,如果直接通过lib链接的话,肯定是会redirect的。所以我们的做法就是在compile时加入define选项重新编译这段源码,以后如果想要重定向时,去掉define选项即可。参考上面网站的做法(有所不同,他的办法我没有成功):
1、将SDL_win32_main.c加入项目中;
2、去掉链接库选项-lSDLmain;
3、在编译SDL_win32_main.o的时候加入-DNO_STDIO_REDIRECT选项(或者在SDL_win32_main.c中加入#define NO_STDIO_REDIRECT一句)。
这样就一切OK了,看吧。
posted @
2010-04-28 22:28 RayRiver 阅读(889) |
评论 (0) |
编辑 收藏
2010年4月11日
GVIM用的是UTF-8,cmd为GB2312,中文输出的时候就会乱码;
将GVIM中的中文转成GB2312时输出正常;
SQLITE open时用的是UTF-8,insert时因为直接取的文件中的内容,输出cmd正常,所以是用的GB2312;
这时候在select中文的时候在GVIM输入中文字,即使用UTF-8,则无法找到GB2312的数据;
在insert时将数据全部转成UTF-8后,直接select UTF-8就能够找到,但输出cmd为乱码;
这样就全部解释清楚了。
现在要做的就是在insert时转为UTF-8,至于cmd那垃圾输出就算了,我可没兴趣为了输出个东西看还要转成GB2312,再次喷下微软。。
posted @
2010-04-11 01:37 RayRiver 阅读(321) |
评论 (0) |
编辑 收藏
2010年3月31日
摘要: 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。
但不同操作系统的动态库由于格式 不同,在需要不同操作系统调用时需要进行动态库程序移植。本文分析和比较了两种操作系统动态库技术,并给出了将Visual C++编制的动态库移植到Linux上的方法和经验。
1、引言
动态库(Dynamic Link Library abbr,DLL)技术是程序设计中经常采用的技术。其目的减少程序的大小,节省空间,提高效率,具有很高的灵活性。
采用动态库技术对于升级软件版本更加容易。与静态库(Static Link Library)不同,动态库里面的函数不是执行程序本身的一部分,而是根据执行需要按需载入,其执行代码可以同时在多个程序中共享。
在Windows和Linux操作系统中,都可采用这种方式进行软件设计,但他们的调用方式以及程序编制方式不尽相同。本文首先分析了在这两种
阅读全文
posted @
2010-03-31 20:28 RayRiver 阅读(451) |
评论 (0) |
编辑 收藏
2010年3月29日
环境的搭建不说了,网上很多。我本人是用GCC,没有用VC完全是因为不熟悉微软的东西,以及不想太过依赖微软(就算依赖至少也得知道到底依赖了他哪些东西)。
其中看到的OpenGL的函数,
以gl开头的函数都是OpenGL的标准函数;
以glu开头的函数都是GLU实用库所提供的函数;
以glut开头的函数都是GLUT工具包所提供的函数;
函数库的内容详见
OpenGL开发库的详细介绍。
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
void
myDisplay(void)
{
// 清除, GL_COLOR_BUFFER_BIT表示清除颜色
glClear(GL_COLOR_BUFFER_BIT);
// 画一个矩形, 四个参数分别为左上角点的x, y坐标, 右下角点的x, y坐标
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
// 保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待), 其作用跟fflush(stdout)类似
glFlush();
}
// 程序入口
int
main(int argc, char *argv[])
{
// 对GLUT进行初始化
glutInit(&argc, argv);
// 设置显示方式
// GLUT_RGB表示使用RGB颜色, GLUT_INDEX表示使用索引颜色
// GLUT_SINGLE表示使用单缓冲, GLUT_DOUBLE表示使用双缓冲
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
// 设置窗口在屏幕中的位置
glutInitWindowPosition(100, 100);
// 设置窗口的大小
glutInitWindowSize(400, 400);
// 根据前面设置的信息创建窗口, 参数将被作为窗口的标题
// 此时并不马上显示到屏幕上, 等到调用glutMainLoop后才能看到窗口
glutCreateWindow("My first OpenGL Program, not \"Hello World\", - -");
// 设置一个函数, 需要进行画图时, 这个函数就会被调用
glutDisplayFunc(&myDisplay);
// 进行一个消息循环
glutMainLoop();
return 0;
}
posted @
2010-03-29 22:05 RayRiver 阅读(383) |
评论 (0) |
编辑 收藏
2010年3月24日
1、添加CMD在这里。
regedit -> \HKEY_CLASSES_ROOT\Folder\shell -> 新建CMD here项 -> 新建Command项 -> 键值cmd /K cd /d %L
2、添加右键以xx程序打开该文件。
regedit -> \HKEY_CLASSES_ROOT\*\shell -> 新建Edit with VimMate项 -> 新建Command项 -> 键值"D:\Program Files\VimMate\vim72\gvim.exe" -p --remote-tab-silent "%1"。其中Edit with VimMate为右键菜单显示的文字,键值为执行的程序,至于-p --remote-tab-silent参数,则是GVIM默认以标签形式打开(不重开新GVIM窗口)。
posted @
2010-03-24 23:03 RayRiver 阅读(465) |
评论 (0) |
编辑 收藏
加了一些技术群,经常会看到一些奇怪的现象。一个新手在群里提了个问题,结果半天没人回答,倒是会跳出四五个卫道士模样的人,指手画脚,指责新手编码风格不好,习惯不好,种种。看上去句句在理,实际上全部放屁。本来编码风格之类的东西就是温饱以后考虑的问题,现在人家连饭还没吃饱,你要他考虑这种奢侈品,那你要么是吃饱了撑的,要么就是纯粹去馋人家。不管回答者水平如何,避而不谈问题本身,去扯那些暂时对新人没有用的东西,那就是方向性的误导。最终的结果,新人完全搞不明白你在说什么,本来简单的问题,弄了半天没搞懂。这是一种严重的不负责任,作为技术上的前辈,你可以不回答,但你绝对不要去误导。
回正题(-。-)。原来从公司拷来的redhat已经被我搞的很乱了,于是萌发了将平台移植到新的虚拟机里,因为对ubuntu相对比较熟悉,所以今天重装了ubuntu的虚拟机。重装途中,困难重重,结果到半夜才勉强搞定。记录一下遇到的问题,以及解决的办法,还有一些东西已备以后查看。
1、取消ubuntu默认的点阵字体
cd /etc/fonts/conf.d
sudo ln -sf ../conf.avail/66-wqy-zenhei-sharp-no13px.conf 66-wqy-zenhei-sharp.conf
2、ubuntu初始安装是没有ftp/telnet的
sudo apt-get install vsftpd xinetd telnetd
其中需要设置:/etc/vsftpd.conf文件中将以下一行注释去掉:local_enable=YES,目的是可以使用linux用户登录ftp(否则只能匿名登录)。
另外还有个问题,在FTP的put时,似乎由于权限问题会put失败,尝试root登录也失败,暂时没有找到原因,以后研究了补上。
3、su - root
ubuntu第一次安装好后默认无法登录root,这时候可以通过下面命令修改root口令,就可以su - root了。
sudo passwd root
4、新增字体
将字体文件拷入/home/.fonts目录下,执行下列命令刷新字体缓存。然后就可以使用新加的字体了。
fc-cache -fv
sudo不sudo无所谓。另外建议将字体的权限改成755,以便其他用户read。
5、最后一个,也是本文的标题,同样也是困扰我一晚上的问题。在SecureCRT登录的时候发现中文有乱码的问题,尝试了网上的一些办法,把编码改UTF-8 GBK都是有问题,最后发现了原来字体的字符集也是有关系的,现在把我改的东西整理如下。
(1)/var/lib/locales/supported.d/local文件中添加一行:zh_CN.UTF-8 UTF-8,执行sudo locale-gen下载文件
(2)在/etc/environment中增加两行分别为:LANG="zh_CN.UTF-8"和LC_ALL="zh_CN.UTF-8"
(3)~/.profile中增加两行分别为:export LANG="zh_CN.UTF-8"和export LC_ALL="zh_CN.UTF-8",执行.profile
(4)SecureCRT中选择终端类型为Linux,选择编码为UTF-8,最重要的是选择一个支持GB2312字符集的字体。因为我常用的Monaco字体不支持,于是我不得不忍痛放弃,在网上找到一个“YaHei Mono”是可以正常显示的,虽然看上去不如Monaco,不过用着慢慢也习惯了吧(记得大学里做毕业设计的时候用netbeans里一个Yahei console字体和这个很相似),具体详见这里。
到此SecureCRT终于可以正常显示汉字了,因为很困了所以只是罗列了一下修改内容,没有写太多的理由。在此我不禁要喷一喷微软,你说你好好的UTF-8不用,都WIN7了还用这么个GB2312,你不是害人吗。
睡了,有修改内容以后补充。
posted @
2010-03-24 01:31 RayRiver 阅读(1102) |
评论 (0) |
编辑 收藏
2010年3月18日
今天看到同事写的代码:
char retcode[5];
memset( &retcode, 0x00, sizeof(retcode) );
因为以前没见过这样的写法,心想retcode本身就是指向字符数组的指针,再加个&不是变成指向指向字符数组指针的指针了吗?结果他告诉我,这样写是可以的,而且可以防止retcode改变类型造成的coredump的情况。
带着怀疑的想法去查了下《C与指针》,还真发现了这种用法。根据书中描述我才知道,这个retcode一般情况下表示的是指向char的
常量指针,只有两种情况,数组名所表示的不是指针常量:
1、当数组名作为sizeof操作符的操作数时。这时sizeof返回的是整个数组的长度,而不是指向数组的指针的长度;
2、当数组名作为单目操作符&的操作数时。
取一个数组名的地址产生的是一个指向数组的指针(和使用数组名效果相同),而不是指向某个指针常量值的指针。
这么一句memset把两种情况都用上了。
------------------------------------------------------------------------------
2010.04.26
今天遇到一个问题,在调zlib的compress的函数的时候总是报Z_STREAM_ERROR,半天都没找到原因,最后发现,我写了下面的代码:
Byte* alObuf;
alObuf = (Byte*)calloc(_MAX_ZMG_BUFFER, sizeof(Byte));
memset(&alObuf, 0x00, sizeof(alObuf));
因为自从知道上面的数组memset的写法以后,就一直习惯在前面加个&。然而,这一次,栽了。。
仔细看,这只是个unsigned char指针,加上了&就完全不知道指哪儿去了。。。
所以,这个写法,只能用在数组前,千万别用在指针前。。。另外,这里的sizeof(alObuf)也只是4而已,指针的sizeof。。。数组和指针,别搞混了。
posted @
2010-03-18 19:35 RayRiver 阅读(455) |
评论 (0) |
编辑 收藏
2010年3月14日
需要用到对informix的两个库的操作,一个是本地库一个是远程库,因为要有交叉操作,所以如果不停的开关会影响效率。
EXEC SQL connect to "db1@online7" as 'db1';
EXEC SQL connect to "db2@online9" as 'db2';
用时指定当前的连接:
EXEC SQL set connection 'db1';
posted @
2010-03-14 18:45 RayRiver 阅读(300) |
评论 (0) |
编辑 收藏
2010年2月25日
需要写一个卸数的工具,有一个SELECT MAX的操作:
1EXEC SQL SELECT MAX(index) INTO :index
2 FROM table
3 WHERE x=:x AND y=:y;
目的是取出满足WHERE条件的index的最大值。但是得出的结果却是-21474836478,十六进制为0x00000080,非常奇怪。尝试了很多次还是这种结果,后来在网上找到了一篇文章(
http://www.tek-tips.com/viewthread.cfm?qid=1501792&page=3),大致意思是当满足WHERE条件的条数为0时,这条语句会有问题。仔细检查才发现我其中的y值取错了,造成符合条件的记录数为0,造成以上的问题,至于index为什么会有那个值原因未知。
结论是:
在使用SELECT MAX之前,需要首先确定满足WHERE条件的COUNT(*)>0,否则会造成未知错误。
PS:至于刚才网址中作者所说的空表时会报-201错我没有碰到,我在空表时和没找到记录时现象相同。
posted @
2010-02-25 23:00 RayRiver 阅读(749) |
评论 (0) |
编辑 收藏
2010年2月11日
研究了一下浮点型在内存中的表示方法,终于明白fortify果然不是吃素的,原来double型数字真的有可能超过200位的。。
一、浮点型在内存中的表示
单精度float型: 1位符号位, 8位阶码(固定偏移 7F), 尾数23, 固定隐含位有
双精度double型: 1位符号位, 11位阶码(固定偏移 3FF), 尾数52, 固定隐含位有
long double型: 1位符号位, 15位阶码(固定偏移3FFF), 尾数64, 固定隐含位无
某些编译器中把long double作double处理
其中,
符号位s:0表示正,1表示负;
阶码e:表示指数,需要减去固定偏移de;
尾数x:表示纯小数位,固定隐含位z是指整数位的1或者0。
表示成十进制就是(-1)^s * 2^(e-de) * (z+x)
对于32位系统,float占32位,double占64位
举例来说,在BIG ENDIAN中二进制表示为01000001 00100000 00000000 00000000的浮点数,根据上面的规则,可以写成:
0,10000010,0100000 000000000 0000000
符号位s=0,阶码e=10000010b=130,固定偏移de=0x7F=127,尾数x=0.01000000000000000000000b=0.25,固定隐含位有,z=1
根据公式可以算出这个数的十进制表示为:(-1)^0 * 2^(130-127) * (1+0.25) = 10.0
二、一些特殊的浮点数
0,00000000,0000000 00000000 00000000和1,00000000,0000000 00000000 00000000均表示0(阶码和尾数都是0)
*,11111111,******* ******** ******** 表示非法数字(阶码是255时)
最大的float数:0,11111110,1111111 11111111 11111111 用10进制表示约为 +3.4e38
最小的float数:1,11111110,1111111 11111111 11111111 用10进制表示约为 -3.4e38
绝对值最小的float数:0,00000000,0000000 00000000 00000001和1,00000000,0000000 00000000 00000001
三、浮点数的精度
单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位。
双精度的尾数用52位存储,2^(52+1) = 9007199254740992,10^16 < 9007199254740992 < 10^17,所以双精度的有效位数是16位。
如果你在浮点数的有效位后增加数字的话,结果是不会变化的。
四、浮点数的取值范围
float取值范围:
负数取值范围为 -3.4028235E+38 到 -1.401298E-45,正数取值范围为 1.401298E-45 到 3.4028235E+38。
double取值范围:
负值取值范围-1.79769313486231570E+308 到 -4.94065645841246544E-324,正值取值范围为 4.94065645841246544E-324 到 1.79769313486231570E+308。
所以说,double型在sprintf的时候,要么想办法回避Buffer Overflow的问题,要么就...给字符数组分配308以上的空间...
posted @
2010-02-11 23:49 RayRiver 阅读(990) |
评论 (0) |
编辑 收藏
2010年2月9日
今天在fortify代码扫描的时候检测出一个HOT,漏洞类型是Buffer Overflow,元凶是sprintf。
1sprintf(aTmp, "16.2f", TransAmt);
其中aTmp是20位字符数组,TransAmt为double型金额字段,值不确定。
理论上来说,是TransAmt按照格式16.2f写进aTmp的时候,有可能产生越界的错误。我一开始考虑将aTmp长度放长后,double应该可以顺利拷进aTmp,尝试将aTmp的长度分配到50,100,200,还是消除不掉这个HOT,因为不明白是double所表示的浮点数的长度有可能超过200位还是fortify认死理,而银行又强制规定代码扫描不能有HOT(-。-),所以将sprintf替换成snprintf。
1snprintf(aTmp, sizeof(aTmp), "16.2f", TransAmt);
需要注意的一点是,第二个参数的值。网上有人提到写成snprintf(buf, 10, "%10s", p)其实是不对的,因为这里的长度,是包括结束符0x00的,也就是说,既然需要按照%10s格式化,那么这里的第二个参数必须写成11而不是10。
相似的,strcpy等不带长度的字符串操作函数,如果不注意写法,往往会有Buffer Overflow的隐患。这时候,一般来说以strncpy等类似的带长度参数的函数替换就可以避免漏洞的产生。
另外,在网上查这个问题的时候,看到一个关于sprintf和snprintf的自拷贝的问题。
1sprintf(buf, "%s world\n", buf);
因为我自己有时候也会有这种写法,但也是不太确定会不会有问题。既然网上已经有明确的研究了,那我就直接拿结论。
关于这两个函数的自拷贝问题,在不同的编译器上,结果不同。编译器可以有不同的策略,有的简单的把原先的值抹去,有的会保留。因此,一般来说,我们应该尽量避免这种写法。
posted @
2010-02-09 23:25 RayRiver 阅读(2058) |
评论 (0) |
编辑 收藏
2010年2月7日
今天准备手动make原來用CODE BLOCKS写的代码的时候报了这么个错误:
1\MinGW\lib\libmingw32.a(main.o):main.c|| undefined reference to `WinMain@16'
大概意思是WinMain未定义。WinMain是windows程序的入口函数,一般来说没有main函数或者main函数名拼写错误的话会在编译的时候报这个错。我检查以后,发现main应该是正确的。
google一下后发现有不少人也遇到这个问题。仔细检查了下Makefile,发现在连接库的时候-lmingw32写在了SDL库的后面,将-lmingw32放在最前面后,问题解决。
posted @
2010-02-07 15:34 RayRiver 阅读(11159) |
评论 (1) |
编辑 收藏