文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>关于以后的文章

关于以后的文章

时间:2010-08-10  来源:eGust

不知道cnblogs的机制是什么,根据后台管理的页面浏览与RSS的统计,“随笔”的阅读量要高于“文章”。不过就内容来说,“文章”的价值要远高于“随笔”的,尤其是对初学者来说。因为随笔一般只针对几个语法知识点,而“文章”的内容则要更基本一些——当然也许这样也导致“文章”会更抽象、晦涩一些,不是很好读懂。一两个语法知识点只能够帮助你更好的应用Delphi,而基础知识对于基于过程的编程语言来说,大体上是通用的——也就是说,到目前为止,“随笔”更多讲的是Delphi特性的东西,而“文章”讲共性的东西更多一些。如果你对自己的基础并不完全自信的话,希望你能读一下目前已经有的“文章”:

作为一门基于过程的语言,Delphi的内容无非包括以下几种:类型,变量,函数。熟练掌握它们,再对Delphi的类库等有足够的了解,就已经可以写出不错的程序了。如果要弄一些更接近操作系统的内容,那就要对WinAPI有一定程度的认识,熟练使用MSDN能快速找到需要的函数;喜欢GUI的话,就要了解基本的GDI对象,理解Windows的消息机制,对VCL的封装模型也要有一定概念。这个时候,就基本上可以独立解决大部分问题,算得上是半个“高手”了。不对是使用类、使用DLL,还是应用接口等等,完全还是围绕类型、变量、函数这几样东西转,只不过形式稍微复杂一些。

我把对Delphi的使用分为三个层级:初级时,对类型、变量、过程只有初步的认识,还不能熟练的匹配;中级时,则要能够有清晰的认识,能够熟练匹配,并且意识到脱离不开它们;到了高级,就可以更意识流一些,眼里看到的只有内存,类型、变量、过程都是为了方便使用才存在的,能够熟练的在看似不同的类型之间进行正确的转换。如果不太高级是什么意思的话,这里可以举个例子:某次写一个小程序,需要计算文件的MD5。开始我直接使用了CnVCL(过去叫CnPack)的CnMD5单元,在处理一个大文件的时候,发现处理速度明显要比用Total Commander的一个插件慢。于是我又对比了一下.Net的库,发现同样也比CnMD5快很多。由于.net直接使用了AdvApi32.dll的导出函数,于是我根据网上搜到的导出函数原型,写出了以下的Delphi声明:

type
        TAdv32MD5       = record
                TotalSize               : Int64;
                buffDigest      : array[0..3]of LongWord;
                buffInput               : array[0..63]of Byte;
                Digest  : array[0..3]of LongWord;
        end;

const
        AdvApi32        = 'AdvApi32.dll';

procedure aaMD5Init(var MD5Context: TAdv32MD5); stdcall;
        external AdvApi32 name 'MD5Init';
procedure aaMD5Update(var MD5Context: TAdv32MD5; const Buffer; Size: LongWord); stdcall; 
        external AdvApi32 name 'MD5Update';
procedure aaMD5Final(var MD5Context: TAdv32MD5); stdcall;
        external AdvApi32 name 'MD5Final';

这样当然是可以正确使用的。不过我用的是D2010,2006后版本的Delphi支持记录类型的成员函数,可以封装一下。于是我利用这个语法支持,写下了另一个版本的声明,使用起来会方便很多:

type
        TMD5dig = record
                Digest  : array[0..3]of LongWord;
                function ToString: string;
        end;

        TAdv32MD5       = record
        private
                TotalSize               : Int64;
                buffDigest      : array[0..3]of LongWord;
                buffInput               : array[0..63]of Byte;
        public
                digest  : TMD5dig;
                constructor Create(const Buffer; Size: LongWord);
                procedure Hash(const Buffer; Size: LongWord);
                class function MD5(const Buffer; Size: LongWord): TMD5dig; static;
                
                procedure Initialize; stdcall;
                procedure Update(const Buffer; Size: LongWord); stdcall;
                procedure FinalDigest; stdcall;
        end;

const
        AdvApi32        = 'AdvApi32.dll';

{ TMD5dig }

function TMD5dig.ToString: string;
const   HexChars        : array[0..15]of Char = '0123456789ABCDEF';
var
        i, b    : LongWord;
        pSrc    : PAnsiChar;
        pDst    : PChar;
begin
        SetLength(Result, 32);
        pDst    := Pointer(Result);
        pSrc    := @Self;
        for i:=0 to 15 do
        begin
                b       := Ord(pSrc[i]);
                pDst[i*2+0]     := HexChars[b shr $4];
                pDst[i*2+1]     := HexChars[b and $f];
        end;
end;

{ TAdv32MD5 }

constructor TAdv32MD5.Create(const Buffer; Size: LongWord);
begin
        Initialize;
        Update(Buffer, Size);
end;

procedure TAdv32MD5.FinalDigest;
        external AdvApi32 name 'MD5Final';

procedure TAdv32MD5.Hash(const Buffer; Size: LongWord);
begin
        Initialize;
        Update(Buffer, Size);
        FinalDigest;
end;

procedure TAdv32MD5.Initialize;
        external AdvApi32 name 'MD5Init';

class function TAdv32MD5.MD5(const Buffer; Size: LongWord): TMD5dig;
var     tmp: TAdv32MD5;
begin
        tmp.Hash(Buffer, Size);
        Result  := tmp.digest;
end;

procedure TAdv32MD5.Update(const Buffer; Size: LongWord);
        external AdvApi32 name 'MD5Update';

观察Initialize、Update以及FinalDigest的声明与实现部分,并没有声明一组导入函数再用成员函数去调用它们,会不会感到很意外?


此外,我还会单独讲讲字符串与编码,尤其是Unicode的问题。编码这种东西其实并不复杂,而且从Win2000开始,Windows内部就已经使用Unicode了。D2009终于原生支持Unicode版的控件了,这一天来的实在太晚了,导致大量Delphi程序员到现在还搞不清它。我始终认为,像Unicode这种东西,对拉丁或者西里尔文使用者来说意义并不大,但作为东亚国家的程序员或者码农——别怪我埋汰你,要是这么简单的东西还整不明白,也就甭笑话国足冲不出亚洲了——你跟他们在各自领域的水平半斤八两。字符串的内容稍微复杂一些,并且由于从D2009开始的变化,我也会对前后的变化进行讲解。


还要再强调一下:我主要以讲解D2010的语法为主,附带内容会提到不同版本间的语法变化(虽然我是从D4开始接触Delphi的,不过那个时候实在是个连OOP都搞不清楚的小白,所以最早提到的也只有D5到D6的变化)。千万不要觉得D2010很神秘,或者编译器本身还有很多bug,影响日常使用——我可以很明确的告诉你,目前D2010的编译器bug要么是新语法的,要么就是从老版本中带来的。当然,部分涉及网络或数据库的类库,在功能上可能会有因Unicode产生的问题,因为我几乎不写网络或数据库功能的程序(就算写大概也会选择C#),所以我无法确定D2010在这些方面到底有没有问题。由于Unicode是未来的趋势,并且据Embarcadero的路线图,未来Delphi可能会支持其它操作系统。相信我,如果连Win32平台的D2010都用不明白的话,你不可能用明白以后的新版本的。

相关阅读 更多 +
排行榜 更多 +
马里奥赛车世界游戏手机版下载

马里奥赛车世界游戏手机版下载

赛车竞速 下载
无畏契约皮肤开箱器手游下载

无畏契约皮肤开箱器手游下载

休闲益智 下载
旭日之城官方正版下载

旭日之城官方正版下载

策略塔防 下载