关于作者

用户名:陈学术
笔名:阿猴
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



家人

志同道合

访问统计:
文章个数:54
评论个数:21
留言条数:1




Powered by BlogDriver 2.1

残留的梦

 

怀着残留的梦想, 我翱翔于Delphi这片广阔的天地, 探索,追求... 联系: QQ:21766374 Email:monkey_cn@tom.com

文章

大学同学Andy的日记!

    “你哭着对我说,童话里都是骗人的,我不可能是你的王子。也许你不会懂,从你说爱我以后,我的天空星星都亮了。我愿变成童话里你爱的那一个天使。。。。。。”微风的怂恿下我睁着眼睛推开宿舍防盗门,舍友阿龙正倚靠在电脑旁伴随音乐的节奏哼着光良的《童话》。看着他表情黯然,目光漂泊。我猜测道应该是在追逐小I的道路上遇到了悬车束马的挫折。不敢劝他重整旗鼓等待着枯枝再春,我尽量束缚语言的膨胀,保持着缄默不语。隔岸观火的我毕竟还是了解他现在的感受,一接触到关于爱情的话题可能就会如同在他血涌如泉的伤口上撒下盐巴一般。

    踏过地上舞动的纸屑,溅起如同浪花飘散的烟灰,我停留在阳台栅栏边盯着橱窗下的篮球若有所思。阳光染红了我的脸颊,在榕树林里撒下一片片闪烁的鱼鳞。此刻,赫然想起连同裤裆里倾巢而出的7条内裤都披挂上阵,尸殍横卧冷桶!面对着这么晴朗的天,如果抵挡不住同学的诱惑再次从篮球场汗流浃背而归,晚上洗澡时岂不是要沦陷到弹尽粮绝的绝境。于是从堆积如山的脏衣服挑出两条内裤在水池中大浪掏沙以解燃眉之急。

2点过后上课不久,选修课老师忽略了我的忠言进谏,征得大部分同学的意见后决定增加课堂互动环节。要求叫到同学在台上发表三分钟关于“我最尊敬的人”的话题演讲。盯着老师蠢蠢欲动的嘴唇,我的心仿佛筐上旋转的篮球一般,听到“ANDY”从老师嘴巴里脱口而出的那一刻球应声入网。果然是出乎意料,第二个便叫上我的名字。没有选择的余地,在同学们热情的掌声中我来不急粉墨便堂皇登场了。“恩,我尊敬的人有很多,比如毛泽东啊邓小平啊希。。。”悬崖勒马似的停滞了言语,背脊不禁冒出冷汗,好险差点把希特勒也脱口而出“希。。。希望象他们一样也能干出一番轰轰烈烈的事业,但谈到最尊敬的人,我想应该是我父亲。因为他在平凡的生活里演绎出我眼中伟大的一面。。。。。。。”讲述了一个平凡的童年往事后,我在雷鸣般的掌声中谢幕。

下课后,在同学阿杰的号召下我换上一双布满沧桑的他冷眼相对的匹克鞋。之所以还没扔掉是因为阿杰认为这双鞋跟他他混了很多年,甚至穿出感情了,觉得它就像隔夜的鸡肋,食之无味,弃之可惜。于是决定让它投靠在我脚上,在它的风烛残年里伴我驰骋完最后一段路程,在我的人生路上撒下几笔夺目的光辉。戴上护腕,跟着大伙4个人龙骧虎步向篮球场迈进。但见篮球场地挨山塞海的,只好添加在几个据说是西藏特招的新生组队打擂台。其中有个红头发的,身高170左右,瘦骨嶙峋的,打球凶悍动作粗鲁。在阿燎上篮被他用暴力阻止后,硝烟弥漫,战争蓄势待发。看着阿燎跟他昂俯对峙,我也抒发了一下不爽的情绪说道“你妈的,打球这么凶,你还蛮横个啥鸟”对方瞪了我一眼。不经意发现他脸上掠过一丝诡笑。后来才明白原来他抓住机遇慎重选择了战场。避开对176的阿燎的冲突,将战争的矛头指向165的我,冲我发起猛烈的攻击。只见他提起臀部连腿带靴放到我怀里,我本能地旋转角度,纵身跃开。他又抬起拳头欲抚摸我的脸颊,我腼腆地拒绝了。据舍友叙述当时的战况是这样的:“他凶神恶煞逼近我,往我肚子踹上一脚,没踹到。接着他又轮起两条胳膊,紧握双拳向我挥来,然而在我眼里,就仿佛两根舞动的稻草一般,不费吹灰之力睹截了他的拳路,一个泰山压顶,轻轻松松地将其推开。”这时劝架的观众蜂拥而上在我们俩之间筑起一道象征着和平的人墙,我趁机权衡利弊:下周又要迎接文明学校质量评估,如果斗殴起来惊动了学校领导,不死也残废了。刹那间,理智战胜了冲动,一道和蔼的目光从我眼眶迸出,温柔地灌溉在他脸上。这意味着我将坚持”退一步海阔天空“的立场,然而事实证明了只是我一相情愿而已。他依然咄咄逼人。这时,身旁的阿燎领悟到我眼神里透露的慈悲。他灵光一现决定用气势振住敌方逼他言和。于是阿燎从口袋里操出家伙,是一架手机,而不是钢刀,以篮球场为革命根据地,运筹帷幄,谴千里之兵,解亥下之围。不一会儿功夫,一大帮兄弟风尘仆仆地赶来。而那西藏奴在我们浩荡声势的威逼下,竟然临危不惧,唇色未更,摆着一幅泰然处之的面孔。僵持片刻,在一位陌生人的调解下,终于湮灭了战场弥漫的硝烟。伴随着我与西藏奴的握手言和,在人生舞台演绎了一场化干戈为玉帛的江湖韵事。

 

 

 

 

 

 

 

04.12.06. 天气:风和日丽

- 作者: 阿猴 2006年04月17日, 星期一 22:12  回复(0) |  引用(0) 加入博采

程序员四大忌 你该如何避免呢?

      从我学pascal的第一天起,我就发誓自己要做一名合格优秀的程序员,但是浮躁,急功近利一直是我最大的缺点,希望自己以后能够彻底改正!因为王选的成功是建立在他近10年隐姓埋名,废寝忘食,黑白不分的研究上,建立在他超乎现象的毅力,建立在惊天动地的执着上!以下文章是对自己最好的启示!

程序员四大忌 你该如何避免呢?
2006.01.13  来自:希赛   
 
一忌:轻易言败,没有自信

  没有永不放弃精神的程序员,只是一个有程序员名号的假程序员。一个真正的程序员,知道在程序设计的过程中,可能会遇到不计其数的困难和问题,可能有极多的挫折和失败,而成功只有一次。

  就为解决一个问题,我们可能连续十几甚至几十小时的坐在计算机前不停的工作。一个问题解决了,可能又有其它的问题出现。而你要是不能坚持下来,可能从前的一切努力都流失了。轻易言败的人请不要做程序员,你不可能成功。执着是最可贵的。

  执着的程序员都是相信自己的人,每时每刻都会鼓励自己,你做的出来,你能解决,你会成功。这样他才能坚持下去。

二忌:浮华不实,自满自大

  夸夸奇谈的人不是优秀的程序员。整个程序设计的过程就是一个研究学习,应用,再研究学习,再应用的过程。一名优秀的程序员决不会认为自己足够好了,不需要再提高了。自满自足的人不会是好程序员,会很快落后以致落伍。所以越是优秀的程序员越是感觉自己懂得少,不会在人前故意卖弄,这并不是故作谦虚,而是实实在在的感受,亲自体会才能明白。

  浮华的程序员会不懂装懂,不停的强调语言的优劣,平台的好坏。追求所谓最新最时尚的技术,停留在表面问题上。或假做深沉,用不适合的方式做不适合的事情。就像孔已己一样,以为知道"茴"字有四种写法就是学问。最后是简单的作不好,困难的也作不好。

三忌:死气沉沉,不求甚解

  优秀的程序员是充满激情和活力的程序员。求知欲和创造欲是原动力。有求知欲你才能不停的学习,有创造欲你才能不停的超越自己。死气沉沉的程序员已经对程序设计失去了兴趣,很快就会主动或被迫离开。

  创造不是指你要发明什么别人不知道的技术或方法,而是说不能仅仅知道怎么做,还要知道为什么这样做。之后你才能创造,其实程序设计的整个过程就是创造的过程。

四忌:强调客观,忽略自身

  很多程序员都是在失败的时候强调客观因素,而优秀的程序员的程序员都是先反省自己。要明白自己缺陷,再努力去学习。没有人事事都做的成功,也没有人生来就什么会做。所以失败了,多想想自身的原因,这样你才会不停的进步,而不是留在原地抱怨。

- 作者: 阿猴 2006年01月18日, 星期三 20:19  回复(0) |  引用(0) 加入博采

英雄主义已经过去了!

以下是某网友针对cscn上关于国产数据库创始人冯玉才报道的评论,说的太好了!太棒了!太符合我的口味了!我看过候捷的书,不止一次提到中国人太强调英雄主义的问题了!都什么年代了!我想说的,以下这位仁兄已经说得很清楚了,中国人真的要醒悟啊:英雄主义已经过去了!

网友评论:

这是一种怎样的悲哀!

    20年,My God!人生几个20年?扪心自问,20年里,你们都干什么了?一个数据库系统开发需要20年这么长时间吗

?20年哪,一个微软帝国都产生了,而我们还在沾沾自喜地为开发出一个别人几十年前就有的技术而兴奋,而狂奔,而

呼喊。

    自主?国产?凭什么?谁给你的权利?凭什么把自己开发的产品说成是国产?在你们使用“国家”这一神圣而不可亵渎的字眼给自己脸上贴金时,你们有没有感觉到半点羞耻?难道仅仅因为你是个中国人就可以无限的透支“国家”的声誉吗?

    自身的技术优势和服务优势?请问你的技术优势在哪里?在性能上是超过了商业版的Oracle、SQL server、DB2、

infomix、sybase,还是超过了免费且开源的MySQL、PostreSQL?依我看,所谓的技术优势充其量也不过是汉字技术比人家稍微强一点点而已。服务优势又在哪里?仅仅是因为客服人员全部可以讲流利的中文就算做是优势吗?这样的行为简直可以称得上可耻了,不,是无耻!而且是厚颜无耻!如果果真如某些人自己所说的那样具有技术和服务优势,“地球是方的”这句话似乎也应该算是真的了。以一次又一次避重就轻的所谓的“企划”来算计善良而无知的人们,这又算什么?卑鄙!

    不要再这样了,动不动就高喊“国产”口号,动不动就高举“民族”大旗,仿佛全中国只有你一个人在为国家做贡献,在为中华民族的伟大复兴而奋斗。算了吧,英雄是让别人评出来的,不是自己挂块“我是英雄”的遮羞布就真的可以算做是英雄了。

    有很多人在默默地为我们伟大的祖国而奉献着,比如说任劳任怨的工人,比如说默默无闻的科学家,比如说精明能干的商人,比如说勤勤恳恳的农民,比如说无私奉献的军人,比如说生命不息、奋斗不止的一代又一代共和国领导人,他们在平凡或伟大的岗位上努力做着自己应该做的事,却没有一天到晚到处用“祖国”的名义给自己做嫁妆。他们有的只是付出,他们想的只是如何做好自己的事情。这才是真的英雄!

    我很怀念鲁迅先生,他眼光是那样的精准,笔锋是那样的犀利。我很庆幸他已不在人世,否则肯定也会被这些整天只知道给自己脸上贴金的骗子气死。只是不知道,在天国的鲁迅先生是不是又在口吐鲜血?

    不要跟我说有本事你也去开发一套之类的话,那不是我的工作,我只知道一个人把自己该做的做好就够了,就是对祖国莫大的贡献,就是一个有用的人。

    我不是作家,所以写不出多好、多精彩的文字来表达我的感受,因为,我不是作家。

    几千年了,孔已己式的阿Q精神不是说没就没的,没办法,只是真的觉得很悲哀!

==================

报道原文:

他们是怎样一群人?他们20年来经历了哪些艰难困苦?他们今天又是怎样迎来了国产数据库的春天?
            讲述国产数据库不为人知的研发历程,与您交流国产数据库的研发以及应用的最新动态。国产数据库 厂商辛苦耕耘近20年,凭借自身的技术实力和服务优势,已经在国防(或其它安全部门)领域得到了较为广泛的运用。
           国产数据库已经从默默耕耘走向了各行业企业应用的前台。CSDN网站数据库频道特邀国产达梦数据库的创始人冯玉才先生走进聊天室,与CSDN网友交流“国产数据库的昨天,今天和明天”。

        达梦数据库有限公司董事长 冯玉才
          
冯玉才,男,1945年10月出生,江苏靖江县人,毕业于哈尔滨军事工程学院。现任华中科技大学计算机学院数据库与多媒体技术研究所所长、教授、博士生导师。1992年获国务院政府津贴;1996年被评为国家有突出贡献的中青年专家;国家软件技术专家组专家;中国数据库标准委员会主任;国务院信息安全咨询专家组成员;教育部信息学部成员。作为国内最早研究DBMS的专家之一,冯玉才教授以振兴民族软件产业为己任,克服重重困难,20多年坚持不懈努力,致力于国产数据库管理系统的研究、开发和推广。1988年,冯玉才教授研制出我国第一个自主版权的国产数据库管理系统原型CRDS,驳倒了中国没有能力开发国产的数据库管理系统的谬论,并在此基础上将数据库与人工智能、面向对象、地理信息、多媒体、网络、图象、图形、安全等多个领域知识的交叉研究,研制出多种数据管理系统的原型及产品。1992年,冯玉才教授创办了我国第一个专业从事数据库技术研究的机构。承担国家级、部级等各种重大项目32项,取得了40多项研究成果,皆为国际先进、国内领先水平,其中12项获国家、省、部委科技进步奖。

        冯玉才访谈摘录

 20年来,我无悔自己的选择,因为我们做出了完全自主知识产权的安全数据库 。”
 
20年前如果我选择做应用软件,我个人和我们的公司的发展道路会平坦,轻松许多,从经济上看也会更成功。”
“发展国产数据库,媒体开导,舆论先行,为国产软件摇旗呐喊,唤醒民众改良中国文化。”


- 作者: 阿猴 2005年12月23日, 星期五 23:53  回复(0) |  引用(0) 加入博采

Delphi精要笔记 5

11:27 2005-12-13
1.自定义系统唯一消息

UINT RegisterWindowMessage(LPCTSTR lpString);
DWORD GetWindowThreadProcessId(HWND hWnd,
    LPDWORD lpdwProcessId
);


例子:

接收端

AppReceive
var
  Id:dword;
begin
  mainform.newOneMessage(var Msg:TMsg;var Handled:Boolean);
  begin
    if Msg.message=Id then
    begin
      showMessage('应用程序收到消息');
      handled:=true;
    end;
  end;

  mainform.formcreate();
  begin
    caption:='接受者';
    ID:=RegisterWindowMessage(P('OneOfAppMessage'));
  end;
 
  mainform.WndProc(var Message:TMessage) override;
  begin
    inherited;
    with Message do if Msg=Id then
    begin
      showMessage('主窗体收到消息');
      result:=0;
    end;
  end;
end;

发送端
AppSend
var
  Id:dword;
begin
  mainform.formcreate();
  begin
    caption:='发送者';
    ID:=RegisterWindowMessage(P('OneOfAppMessage'));
  end;
 
  mainform.button1Click(sender.Tobject);
  begin
    H:=FindWindow(nil,pchar('接受者'));
    if H<>0 then
    begin
      sendMessage(H,ID,0,0);
      PostThreadMessage(GetWindowThreadProcessId(H),ID,0,0);
    end;
  end;
end;

- 作者: 阿猴 2005年12月14日, 星期三 01:50  回复(0) |  引用(0) 加入博采

Delphi精要笔记 4

19:40 2005-12-9

发送消息的多种方法


1).给指定窗口发送消息

 给窗口发送消息:
  function SendMessage(hWnd:HWND;Msg:UINT;wParam:WParam;lParam:LParam):LRESULT;stdcall;
  function DispatchMesage(const lpMsg:TMsg):Longint;stdcall;
------------------------------------------------------------------------------
  function PostMessage(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LParam):Bool;stdcall;
2) 给应用程序发送消息:
  function SendAppMessage(Msg:Cardinal;wParam,lParam:Longint);

3) 给线程发送消息
  function PostThreadMessage(idThread:DWORD;Msg:UINT;wParam:WPARAM;lParam:LPARAM):BOOL;stdcall;

  获取idThread可用Api函数得:
  function GetWindowThreadProcessId(hWnd:HWND;lpdwProcessId:Pointer=nil):DWORD;stdcall;overload;
  function GetWindowThreadProcessId(hWnd:HWND;var dwProcessId:DWORD):DWORD;stdcall;overload;

今天郁闷啊,去玩魔兽输了两盘,好没面子,以后不玩了,魔兽bye了!虽然你很完美,但是与你无缘了,但是我盼望着在未来的某一天我可以开发一款像你这样的游戏!加油,加油,继续加油!

- 作者: 阿猴 2005年12月9日, 星期五 20:57  回复(0) |  引用(0) 加入博采

Delphi精要笔记 3

21:23 2005-12-8

1.变体记录

type
  TMessage=packed record//Using packed slows data access and, in the case of a character array,  

                        affects type compatibility (for more information,
    msg:Cardinal;
    case Integer of
  0:(
    WParam:Longint;
    LParam:Longint;
    Result:LongInt;
  );
  1:(
   WParamLo:word;
   WParamHi:word;
   LParamLo:word;
   LParamHi:word;
   ResultLo:word;
   ResultHi:word;
  );
end;
以上是vcl消息定义

typedef struct {
    HWND hwnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD time;
    POINT pt;
} MSG, *PMSG;
系统消息结构定义

2.vcl中两种消息派遣
  
  vcl消息机制的整个流程如下:
Windows->Delphi Application->(TWinControl)MainWndProc->WndProc->Dispatch->Handler

  (1)Application->dispatchMessage(const lpMsg:TMsg)根据参数lpMsg的接受者句柄字段,将消息正文发给

该句柄对应的窗口控件在windows中注册的窗口过程:Twincontrol.MainWndProc.所以到这里,消息就传递给

Twincontrolle了。这是在Windows中派遣,是底层Api函数的调用。
  (2)TObject.Dispatch(var Message);
  Dispatch首先在本类中查找相应的消息方法,如果没有找到,那么逐级上溯父类,祖先类,直到找到对应的

消息方法。
  procedure Tobject.Dispatch(var Message)
  begin
   搜索Handler;
   如果没有找到就调用DefaultHandler(var Message);
  end;

- 作者: 阿猴 2005年12月9日, 星期五 20:13  回复(0) |  引用(0) 加入博采

和伟哥合作愉快

今天和伟哥合作期末课件制作作业,他负责图片处理,我负责编程,整理资料。看完自己两个人合作的作品,有声音有图片,有他的辛苦,也有我的辛劳,真的是一种莫大的享受。合作真的是一种享受!

                                                                                                2005.12.5 23:55

- 作者: 阿猴 2005年12月5日, 星期一 23:57  回复(0) |  引用(0) 加入博采

学会等

      今天和表哥刘勇,堂弟陈臣一起去离家不远的榕树下钓鱼。风很大,水面极不平静,浮标在水中晃来晃去。更糟的是水中还有渔民拿着现代化工具在电鱼。鱼被电后,都失去平衡浮了上来,连巴掌大的鲤鱼也难逃厄运。这明显不是钓鱼的好时机,但是刘勇的表哥实在令我佩服:在开始的一小时颗粒无收的情况下,他仍然没有失去信心,我都不知道是什么力量支撑着他。功夫不负有心人,在我快要崩溃的时,终于钓上了一只两个手指大的非洲鲫鱼。顿时我们三个人的信心都大大地提高了。之间,出现了没有鱼饵的危机,我还特地去挖了几只,以补充弹药。后来到5点多左右我们总共钓了4只。虽然这个周末下午过得有点无聊,但是我从表哥的身上切实地体会到了耐心是人生不可缺的。机会就像鱼一样
,在你快要失去信心准备放弃时候出现了。所有要想抓住机会,你要学会等,学会等到机会消失的最后一刻!

      最近看英语阅读,碰到一些文史经济类的文章,我都不是很懂。自己的文史,经济类的知识要好好地去补补了!

                                                                  05.12.4 星期日

- 作者: 阿猴 2005年12月5日, 星期一 09:00  回复(1) |  引用(0) 加入博采

Delphi精要笔记 2

14:36 2005-11-30

1.操作有序变量的函数:
Ord()
Pred()
Succ()
High()
Low()

2.Boolean类型

Boolean//一个字节
{以下四个是用以兼容操作系统的}
ByteBool//一个字节
WordBool//两个字节
LongBool//四个字节

3.枚举和子界
TColors=(Red,Blue=5,Green,Yellow,Orange,Purple);
TMyColors=Green..Purple;

4.Real
声明变量时用Double和Single,在用做参数传递时用Extended.

5.过程类型和方法类型

Type
{过程类型:}
TMyFunction = function(参数列表):返回类型;
TMyProcedure = procedure()(参数列表);
{方法类型:}
TNotifyEvent= procedure(Sender:TObject) of object;

6.Variant类型
Variant类型有三个状态:Unassigned,Null,非Null

7.类型别名

type DWORD =LongWord;//任何时刻DWORD和LongWord都是相容的
type
  HWND = type LongWord;//用于var和out参数等要求严格类型匹配的地方时,被认为不兼容

- 作者: 阿猴 2005年12月2日, 星期五 00:03  回复(0) |  引用(0) 加入博采

Delphi精要笔记 1

最近到图书馆里借了一本Delphi好书-《Delphi精要》。说实在的,国内的Delphi书有95%是垃圾,
大都是网上的技巧,代码堆积起来的,通常一本书30分钟就可以搞定。但是这本技术书写得有点武侠
版的味道,而且都是作者切身的经验体会,可以和我先前看过的台湾的牛人陈宽达的《Delphi深度历险》
相提并论。好书当然要做笔记了,以下就是俺的看书笔记。
2005-11-29
1.集合:
定义
TOneSet= set of (A,B,C);//全集
声明
partSet=[A,B];
运算
+:
partSet=partSet+[B];//等价于:Include(partSet,B);
-:
partSet=partSet-[B];//等价于:Exclude(partSet,B);


2.指针
除了pchar类型的指针变量,其他类型的指针变量是不允许进行加减运算的

@I等价于addr(I)

3.编译时函数:
编译时函数可以在声明中调用如:
var
  R1:Word=Trunc(12.6);
编译时函数列表:
ord()
chr()
Trunc()
Round()
High()
Low()
SizeOf()

4.DLL
  1)在DLL中编写的函数或过程都必须加上stdcall调用参数.
 
library Delphi;
uses
SysUtils,
Classes;

function TestDll(i:integer):integer;stdcall;
begin
Result:=i;
end;

exports
TestDll;
begin
end.

  2)当使用了长字符串类型的参数、变量时要引用ShareMem。
 Delphi中的string类型很强大,我们知道普通的字符串长度最大为256个字符,但Delphi中string类型在默认情况下长度可以达到2G。(对,您没有看错,确实是两兆。)这时,如果您坚持要使用string类型的参数、变量甚至是记录信息时,就要引用ShareMem单元,而且必须是第一个引用的。既在uses语句后是第一个引用的单元。如下例:
uses
ShareMem,
SysUtils,
Classes;
  还有一点,在您的工程文件(*.dpr)中而不是单元文件(*.pas)中也要做同样的工作,这一点Delphi自带的帮助文件没有说清楚,造成了很多误会。不这样做的话,您很有可能付出死机的代价。避免使用string类型的方法是将string类型的参数、变量等声明为Pchar或ShortString(如:s:string[10])类型。同样的问题会出现在当您使用了动态数组时,解决的方法同上所述。
  3)静态调用例子:
  unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

//本行以下代码为我们真正动手写的代码

function TestDll(i:integer):integer;stdcall;
external ’Delphi.dll’;

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=IntToStr(TestDll(1));
end;

end.
4)动态调用:
这一点很重要,使用静态调用方法时要求所调用的DLL文件以及要调用的函数或过程等等必须存在。如果不存在或指定的路径和文件名不正确的话,运行主程序时系统会提示“启动程序时出错”或“找不到*.dll文件”等运行错误。

                  第四章 在Delphi中动态调用DLL top

  动态调用DLL相对复杂很多,但非常灵活。为了全面的说明该问题,这次我们举一个调用由C++编写的DLL的例子。首先在C++中编译下面的DLL源程序。

#include

extern ”C” _declspec(dllexport)
int WINAPI TestC(int i)
{
return i;
}

  编译后生成一个DLL文件,在这里我们称该文件为Cpp.dll,该DLL中只有一个返回整数类型的函数TestC。为了方便说明,我们仍然引用上面的调用程序,只是将原来的Button1Click过程中的语句用下面的代码替换掉了。

procedure TForm1.Button1Click(Sender: TObject);
type
TIntFunc=function(i:integer):integer;stdcall;
var
Th:Thandle;
Tf:TIntFunc;
Tp:TFarProc;
begin
Th:=LoadLibrary(’Cpp.dll’); {装载DLL}
if Th>0 then
try
Tp:=GetProcAddress(Th,PChar(’TestC’));
if Tp<>nil
then begin
Tf:=TIntFunc(Tp);
Edit1.Text:=IntToStr(Tf(1)); {调用TestC函数}
end
else
ShowMessage(’TestC函数没有找到’);
finally
FreeLibrary(Th); {释放DLL}
end
else
ShowMessage(’Cpp.dll没有找到’);
end;

5)
一、编写技巧。
  1 、为了保证DLL的正确性,可先编写成普通的应用程序的一部分,调试无误后再从主程序中分离出来,编译成DLL。

  2 、为了保证DLL的通用性,应该在自己编写的DLL中杜绝出现可视化控件的名称,如:Edit1.Text中的Edit1名称;或者自定义非Windows定义的类型,如某种记录。

  3 、为便于调试,每个函数和过程应该尽可能短小精悍,并配合具体详细的注释。

  4 、应多利用try-finally来处理可能出现的错误和异常,注意这时要引用SysUtils单元。

  5 、尽可能少引用单元以减小DLL的大小,特别是不要引用可视化单元,如Dialogs单元。例如一般情况下,我们可以不引用Classes单元,这样可使编译后的DLL减小大约16Kb。

二、调用技巧。
  1 、在用静态方法时,可以给被调用的函数或过程更名。在前面提到的C++编写的DLL例子中,如果去掉extern ”C”语句,C++会编译出一些奇怪的函数名,原来的TestC函数会被命名为@TestC$s等等可笑的怪名字,这是由于C++采用了C++ name mangling技术。这个函数名在Delphi中是非法的,我们可以这样解决这个问题:
改写引用函数为
function TestC(i:integer):integer;stdcall;
external ’Cpp.dll’;name ’@TestC$s’;
其中name的作用就是重命名。

  2 、可把我们编写的DLL放到Windows目录下或者Windows\system目录下。这样做可以在external语句中或LoadLibrary语句中不写路径而只写DLL的名称。但这样做有些不妥,这两个目录下有大量重要的系统DLL,如果您编的DLL与它们重名的话其后果简直不堪设想,况且您的编程技术还不至于达到将自己编写的DLL放到系统目录中的地步吧!

三、调试技巧。
  1 、我们知道DLL在编写时是不能运行和单步调试的。有一个办法可以,那就是在Run|parameters菜单中设置一个宿主程序。在Local页的Host Application栏中添上宿主程序的名字就可进行单步调试、断点观察和运行了。

  2 、添加DLL的版本信息。开场白中提到了版本信息对于DLL是很重要的,如果包含了版本信息,DLL的大小会增加2Kb。增加这么一点空间是值得的。很不幸我们如果直接使用Project|options菜单中Version选项是不行的,这一点Delphi的帮助文件中没有提到,经笔者研究发现,只要加一行代码就可以了。如下例:

library Delphi;

uses
SysUtils,
Classes;

{$R *.RES}
//注意,上面这行代码必须加在这个位置

function TestDll(i:integer):integer;stdcall;
begin
Result:=i;
end;

exports
TestDll;

begin
end.

  3 、为了避免与别的DLL重名,在给自己编写的DLL起名字的时候最好采用字符数字和下划线混合的方式。如:jl_try16.dll。

  4 、如果您原来在Delphi 1或Delphi 2中已经编译了某些DLL的话,您原来编译的DLL是16位的。只要将源代码在新的Delphi 3或Delphi 4环境下重新编译,就可以得到32位的DLL了。

[后记]:除了上面介绍的DLL最常用的使用方法外,DLL还可以用于做资源的载体。例如,在Windows中更改图标就是使用的DLL中的资源。另外,熟练掌握了DLL的设计技术,对使用更为高级的OLE、COM以及ActiveX编程都有很多益处。

- 作者: 阿猴 2005年12月1日, 星期四 15:37  回复(1) |  引用(0) 加入博采