2007年06月存档 - 李凡希的Blog

libeasycgi

  经过两个工作日的审核,终于成功在SourceForge上创建了一个项目,名为libeasycgi(SF Project页面http://sourceforge.net/projects/libeasycgi)。

  这个项目试图实现一个方便用C++进行Web CGI程序开发的一个库,主要的目标是:

  • 借鉴ASP的一些模式(主要指ASP中那几个对象)使C++开发CGI程序可以有一个比较方便、确定、易维护的模式。
  • 提供一些常用的机制,如输入合法性检查、HTML Injection Attack保护等,使CGI开发出程序有一个基本安全保证。
  • 提供一种机制让CGI程序具有更好的可测性,使自动化测试的可能性可以提高。

  创建这个项目前在SourceForge上搜了一下相关的项目,很多,但试了一下,基本上都不好用。除此之外,没有做更多的Research,所以可能这个项目又是有点在“造轮子”了。而且用的还是CGI和ASP这样的“过时”技术,不过没关系,醉翁之意不在酒,自己开这个项目的主要目的是:

  • 自己实践一个完整项目设计、开发、发布过程
  • 尝试熟悉一些开源系统和软件的使用,包括:Emacs, Subversion, autoconf, CppUnit, doxygen, rpm, gcc, apache, php, mysql
  • 尝试实践:跨平台程序的开发,G11N,XP & TDD。

  Scope还是挺大的,一步步来~一开始先只在Linux上做,也不用autoconf,打算先实现一个很简单Prototype,然后依据从Prototype中得到的经验,进行一下设计,然后再一步步完善。

  今天创建了项目,发现SourceForge果然还是很强大的提供一整套完整的服务:Tracker, CVS, SVN, Web (with PHP, CGI and MySql), SSH, Mailling List, File Release System等等,而且除了规定这些设施只能用于项目开发以外,其它的限制并不多,比花钱租一个虚拟服务器可强多了。

菊次郎の夏

  一部很温馨的电影。

  很少欣赏日本的电影,倒也不是有什么偏见,可能只能总结成不合口味吧。日本的恐怖片看过了,没有什么感觉。日本的推理小说看了不少,但拍成电影往往又觉得无味。日本的动漫向来不在我欣赏的范围之内……

  在视觉和心灵被不少美国大片冲击到麻木之后,我越来越喜欢看点轻松的影片来放松自己。菊次郎的夏天就是其中的一部。很久前CCTV-6的一个简单的介绍让我最初知道了这部影片,最近又了解到这部影片的配乐是久副盛名的日本配乐大师久石让的作品之一,所以决定看一下。

  故事很简单:一个不快乐的中年人,一个不快乐的小孩子,一同走在一条漫长的寻找妈妈的路上。路途很遥远,它充满艰幸,它充满欢乐。表情木讷的小男孩正男的一路奔跑、北野武扮演的怪怪大叔一同构成了影片的基调,而路上遇到的形形色色的人,则成为了点缀在这个沉闷旅途中的点点繁星。

  寻找的旅途是一个希望的旅途,然而当旅途的终结于相逢不能相见的希望破灭时,无论对于电影中的人物,还是我们这些电影外的看客,都是不好受的。当希望的破灭、情感的升华让影片变的沉重的时候,喜剧性的巧遇把更多的欢乐、更多的阳光、更多的童年带入了影片。蓝蓝的天,广阔的大海沙滩,绿色的庄稼,青蛙,毛毛虫,闪闪的星空,“一二三,木头人”游戏,“外星人”,“印弟安人”,“八爪鱼先生”让所有人感到了轻松和童年的回归。大人们为了孩子创造着各种各样的快乐,这些快乐又何尝不是他们自己的快乐呢?

  正男在影片中几次微笑也给我留下了深刻的印象,也许这些平凡的笑容也只有在与他那始终如一、不动声色的木讷表情发生这样的鲜明的对比的时候才能给人这么多特别的感触。这些笑容是真诚的,是发自内心的,观众愿意与他一同微笑。

  从拍摄的角度,影片用了不少的长镜头来表现心情或是景色,同时也插入了一些用于表现梦境的希奇古怪的画面。用相册中“活动相片”的方式把影片分成几个故事段落也是很有创意的做法。还有一些值得一提的特殊视角的画面,比如从杯子底拍摄啤酒倒入的过程,用棱镜重复画面表现从蜻蜒复眼中看到的景物,都是非常有意思。导演也许希望通过这些特殊视角的画面让观众领悟到,从很多时候,我们也许需要从更多的视角去看待各种事物。

  比较这部电影与《千里走单骑》,它们拥有心愿的旅程这个共同的主题,也拥有风景、大人、孩子这些共同的元素。但是从表现手法上来看,差别还是不小的。单骑更多的从一些刻意塑造出来的东西中去增强它的感染力,而菊次郎则是从不经意中、从温暖的夏日阳光中让每一位观众记住这个菊次郎和正男共同的特别的暑假。谈不足的话,也许是过于轻松吧,感觉情节不是很紧凑,不过幸好有这么多有趣夸张的故事和美丽的画面,不至于让人放松到睡着。

  谈配乐。这是我第一次关注久石让的作品。第一印象就是很浓厚的东方风味,这跟以前听的很多美国片的配乐或是莫里康尼的那几部意大利片子的风格都很是不一样。一开场的音乐就是影片的主题音乐--Summer,这一音乐主题在影片中多次出现,配合不同的情节进行一些小小的变奏和乐器的变换,来塑造不同的氛围。尤其是在正男奔跑的时候,这段音乐往往会出现,钢琴音符的跳跃,正好衬托着他轻快的脚步。另一段重要的音乐主题是Mother,主要用在与母亲相见不能相认这一悲伤的时刻,小提琴的柔美音色,恰当好处的表现了当时惆怅的心情。总体来说的影片的配乐虽然没有非常的丰富,不过还是很能在需要的时刻去营造出恰当的氛围。上网一搜才知道原来我以前还看过一部久石让的作品,那就是我看过的唯一一部日本动漫电影《千与千寻》,可惜那时候我还没有开始刻意的去注意电影的配乐,印象不是很深刻了,但从对那部影片的感觉的回忆中来看,那部影片在一些关键情节时音乐的烘托应该还是做的很到位的。

  如果看电影时你没有注意,你可能就不会想到影片一直留到最后一刻的悬念:菊次郎到底是谁呢?也许很多人都会从一开始就把菊次郎认为是影片中的小孩子主角正男。如果你没有看过电影,看这篇Blog也不够仔细,你可能还是没有知道菊次郎是谁……^_^

又撞墙了

  原先就知道老老实实呆在家里是没事的,如果牵着狗狗出去逛逛,一不留神就会撞到墙上,撞得头破血流,撞得狗狗找不着北。今天发现,原来不牵着它,让狗狗自己走在回家的路上,也会撞上墙。

  故事是这样的:以前总是让狗狗带着找路,后来发现狗狗身上背的小邮筒挺好使的,就把自己的邮件让狗狗帮忙收发。再后来又发现,狗狗还能帮忙把分布在各家门前的信箱的信件全部拿回来,而且还能把类别分的清清楚楚的,贴上不同的标签。更重要的是,它还会帮忙把那些信箱里的没有用的垃圾清理干净,把那些广告啥的扔到它的垃圾筒里,而且准确率极高。于是就把自己的N个信箱的全部信件都交给狗狗管理了。它也非常的尽责,总是很及时的跑遍所有的地方把邮件取回来,理整好再交给我。

  可是这几天,好像狗狗一直偷懒没有去取信。正想责备它,却看到了它头上的鼓鼓的包,问问它怎么回事,回答说:拿263号信箱的时候不知怎么的信箱门就突然关上了。一直重试,于是撞的满头包。于是,我气乎乎的想去找邮局算帐。可是我自己去信箱拿信试试,发现一切都是那么的正常,所以,似乎邮局也没错……难道邮局不允许狗狗代为取信了?应该不会啊,我跟狗狗取信的方法是一样的啊,都是走的国际标准一千九百三十九号指定的流程啊。

  顾不上处理狗狗遭遇,先自己处理一下那一堆狗狗没拿回来的信件吧。垃圾还真是多……一封封慢慢看吧……突然看到一个精致的信封,似乎很有吸引力,打开一看,唉……精美的信纸上还是印上了些非常不“和谐”的内容,似乎跟什么轮子有点关系,只好随手把它扔进垃圾箱。忽然间,对狗狗头上的包有所感悟,原来,那堵无形的墙,不只在出门的时候撞得上,回家路上,要是遇到什么不“和谐”的东西,它一样会撞得你晕晕的。

  唉,从今往后就得留神着狗狗头上包了,如果撞了,就得自己去把那些会招来墙的信件处理掉了。麻烦啊……

  这几天去看英文百科全书不会撞墙了,去找找各个博客的家也不会撞了,甚至一个被墙围起来的博客小区也可以进去了。可是那个出色的照片博物馆的照片陈列广场却被墙圈起来了。

  没办法,期待有一天,我们真正的可以跨越“长城”,走向世界!

超级玛丽最低分爆机

  为了响应党的号召,营造和谐社会。决定在不破坏公物、不欺负小动物、不踩花花草草、不抢银行、拾金不昧、充分利用时间的前提下从城堡中把公主救出。

  花了差不多一个小时,终于基本实现了这个目的:

  

超级玛丽700分通关
超级玛丽700分通关

  上网搜了下,好像这个700分已经是公认的最低分了。达到这个目标的关键点主要包括:

  • 不打开宝箱,不踩小动物,不吃金币
  • 在关底的时候要在倒计时结束的时候从棋杆的最低处降旗(这样才能拿到最低的100分)
  • 必须按1-1>1-2>4-1>4-2>8-1>8-2>8-3>8-4的顺序完成游戏

  700分是包括了1-1、4-1、8-1、8-2、8-3的五次降棋和在8-1中不得不吃的一个金币的200分。

  难点主要有下面几个地方:

  • 4-2中为进入选关画面的“爬天窗”,需要从跳板上直接把藤条顶出来,落地后往回跳上跳板再跳上藤条
  • 8-1中两个大跳,第一个大跳就是唯一个的必须吃到金币的地方,我是直接跳过去的。有朋友用“踩墙跳”的方法跳这个地方,还是难免要吃到一个金币。但我总觉得这里还是有希望通过踩墙跳不吃金币跳过去的,太难了,我是不指望做到了。第二个大跳也是中间很容易吃到金币,采用的做法是按A的时间短一点来降低跳跃的高度。
  • 8-4中为了进入海中需要跳上一个半空中的水管,正常的做法是撞出它左边的一个金币墙,然后跳上去。为了少吃金币就只能另想办法跳了,有朋友是也是通过“踩墙跳”跳上去的,可惜我总是不成功。突然想到小时候在红白机上玩的时候发现的一个技巧:往右走一点,直到管子与屏幕左边缘相距不到一个人宽的时候,回头从夹缝中往上跳,这时人会卡在水管的底部不掉下来,然后继续再跳一下就行了:)

  如果不想通过选关来完整的把它玩下也是可以的,不过最低过关分数将是2600分。因为要降24次旗是2400分,加上那个不得不吃的金币就是2600分。如果这样玩,在4-3关会有一个新的困难:为了不踩乌龟(鸭子?)、不吃金币,需要连续做四次条件苛刻的大跳。

  借别人一句话结尾:嗯,发现我真的很无聊。

何在C++中动态分配二维数组-续

  回头看一下前一篇《如何在C++中动态分配二维数组》才发现它是挂羊头卖狗肉,文中只提了从ChinaUnix上拿来的那个C的实现,还是没有结论说对于C++的对象应该怎么处理。今天抽空写了一下。

  关键点还是在于placement new和显示的析构函数调用,用于保证对象可以正常的构造和析构。

  不过这个实现也还是有不少缺点的,比如,数组的大小必须记住,才能保证析构所有对象。不过这点可以通过改进分配方法算法,把数组大小也用一点空间保存起来。

  另一个缺点是,从语法上看,很容易让人误把darray_new返回的指针以为是数据区的起始地址,从而可能导致一些逻辑错误。

  其实正像ftofficer在前一篇文章的留言中说的那样,最好的办法还是不要“造轮子”了,有强大的Boost放在那里不用实在是太浪费了……

#include <iostream>
#include <cstdlib>
#include <new>

template <typename T>
T **darray_new(int row, int col)
{
    int size = sizeof(T);
    void **arr = (void **) malloc(sizeof(void *) * row + size * row * col);
    if (arr != NULL)
    {
        unsigned char * head;
        head = (unsigned char *) arr + sizeof(void *) * row;
        for (int i = 0; i < row; ++i)
        {
            arr[i] =  head + size * i * col;
            for (int j = 0; j < col; ++j)
                new (head + size * (i * col + j)) T;
        }
    }
    return (T**) arr;
}

template <typename T>
void darray_free(T **arr, int row, int col)
{
    for (int i = 0; i < row; ++i)
        for (int j = 0; j < col; ++j)
            arr[i][j].~T();
    if (arr != NULL)
        free((void **)arr);
}

火车

  五一期间折腾火车票时认识了一个火车爱好者,才知道这世上还有火车迷这一爱好。于是乎去转了转海子铁路网论坛,发现火车还真是个挺有意思的东东。MS我一直比较喜欢所谓“有技术含量”的东东,看看这些不同的车头车底,加上各种术语,还有车迷口中对火车的“专用名词”,嗯,足够有“技术含量”了也足够吸引我了。

  爱好火车有个很实用的地方就是出行可以比较方便,因为车迷总能在各种条件下找到一个相对最合理的乘车方法。比如南京到北京,Z50/Z6对于不坐飞机的有钱人是不二的选择,但对于我等穷人,最实惠的车应该是T66硬卧,但T66的票不好买,到点又比较晚,所以T736到扬州转个Z30硬卧成为了最佳的备选方案。开点到点都不错,T736是BSP的车底,舒适度很好,Z30条件比T66强,总价格比Z50便宜四分之一,在南京把票买好,到扬州后过天桥上一站台直接上车,也不折腾。(不过今年4月18号“六提”之后T736改成T782,时间上有点悬乎了,一旦晚点,可能就得等着Z30开出后才能到进扬州了,此现象车迷称为“被猪踩了”,“猪”是指直特列车或它的DF11-G车头,“踩”就是指“待避”也就是等车)

  今天看到一则新闻,也是讲中转车的好处,不过不是省钱,是省时间。可惜可怜的记者在车迷眼中成了笑柄一把,更可怜我是在看了三遍以后才看出其中的漏洞的,你能看出来吗(这个漏洞其实跟火车关系不是太大)?

======

  昨日,记者从南昌火车站获悉,南昌火车站已开售异地D字头高速列车火车票,时限在20天内。这意味着,市民可在南昌购买上海开往南京、北京、苏州、镇江等地高速列车车票。

  记者了解到,以往,市民如果要乘火车去南京的话,通常是乘坐2240次南昌—南京西的普通快车,14:29从南昌站发出,次日7:38分抵达南京,总耗时要17个小时,非常漫长。而如果乘客购买异地动车组车票的话,则可节省10个多小时,可在南昌火车站购买南昌—上海南的D92次列车和上海—南京的D434次列车车票。这样的话,早上8:34分从南昌站出发,13:58分到达上海南站,14:33分再从上海站出发,16:53分抵达南京站,总耗时8.5个小时,比2240次节省了近10个小时。

如何在C++中动态分配二维数组

  这个问题应该是我在CSDN蹭分时回答次数比较多的一个问题了,我的回答一般是三种方法:(1)用vector的vector,(2)先分配一个指针数组,然后让里面每一个指针再指向一个数组,这个做法的好处是访问数组元素时比较直观,可以用a[x][y]这样的写法,缺点是它相当于C#中的一个锯齿数组,内存空间不连续。(3)直接分配一个x*y大小的一维数组,这样保证空间是连续的,但访问数组元素不直观。对于我这个“经典”回答,我那时还一直是挺得意的,至少从蹭分的角度来看,这样回答还是很有效的。

  今天在ChinaUnix论坛闲逛时看到一个贴子,再次证明了我在C++方面才疏学浅。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void **darray_new(int row, int col, int size)
{
        void **arr;

        arr = (void **) malloc(sizeof(void *) * row + size * row * col);
        if (arr != NULL)
        {
                void *head;

                head = (void *) arr + sizeof(void *) * row;
                memset(arr, 0, sizeof(void *) * row + size * row * col);
                while (row--)
                        arr[row] = head + size * row * col;
        }
        return arr;
}

void darray_free(void **arr)
{
        if (arr != NULL)
                free(arr);
}

  嗯,连续分配内存,而且可以用a[x][y]的方式来访问!可谓二维数组动态分配的绝妙方法!这段程序是C的,似乎要改成支持对象分配的C++版也不是什么难事(不过估计得用上placement new吧,嗯,需要再思考一下……)。

Introduction

Face   李凡希,江苏吴江人。热爱计算机,勤于探索,愿意与您交流心得。

Miniblog

Subscribe RSS Feed


订阅到抓虾
Add to Google

Contact

Email: Email
Messenger: Live Messenger
GTalk: Google Talk
HAM Radio:BG4XTR

Visitors

Locations of visitors to this page

Links

Archive