﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-射手的博客-随笔分类-Libraries and packages（库和包）</title><link>http://www.cnitblog.com/Archer/category/8228.html</link><description>学习Delphi,需要一个记录学习的博客,</description><language>zh-cn</language><lastBuildDate>Wed, 28 Sep 2011 11:01:47 GMT</lastBuildDate><pubDate>Wed, 28 Sep 2011 11:01:47 GMT</pubDate><ttl>60</ttl><item><title>Delphi library (库) 的学习</title><link>http://www.cnitblog.com/Archer/archive/2009/04/13/56302.html</link><dc:creator>Archer</dc:creator><author>Archer</author><pubDate>Mon, 13 Apr 2009 03:20:00 GMT</pubDate><guid>http://www.cnitblog.com/Archer/archive/2009/04/13/56302.html</guid><wfw:comment>http://www.cnitblog.com/Archer/comments/56302.html</wfw:comment><comments>http://www.cnitblog.com/Archer/archive/2009/04/13/56302.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Archer/comments/commentRss/56302.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Archer/services/trackbacks/56302.html</trackback:ping><description><![CDATA[<span  style="color: rgb(0, 0, 102); font-family: verdana; "><div class="posttitle" style="padding-top: 5px; padding-right: 0px; padding-bottom: 5px; padding-left: 0px; "><br></div>&nbsp;<p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span>Delphi Libraries(Delphi&nbsp;</span><span>库<span>)</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>简介<span>:</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Object Pascal&nbsp;</span><span>中&#8220;动态掉入库（<span>dynamically loadable library</span>）&#8221;<span></span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><span>&nbsp;&nbsp;&nbsp;</span></span><span>在<span>&nbsp;Windows</span>下 以名称为&#8220;动态链接库&#8221; 后缀名为&#8220;<span>.DLL</span>&#8221; 形式的文件出现在系统当中<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><span>&nbsp;&nbsp;&nbsp;</span></span>在<span>&nbsp;Linux&nbsp;<span>&nbsp;&nbsp;</span></span>下以名称为&#8220;共享目标库&#8221;后缀名以&#8220;<span>.so</span>&#8221; 形式的文件出现在系统当中<span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">本文主要讲解的是在<span>Windows&nbsp;</span>中使用<span>&nbsp;Borland Delphi&nbsp;</span>开发软件 进行对&nbsp;<span>&#8221;</span>动态链接库<span>-DLL</span><span>&#8221;</span><span>&nbsp;</span>规则讲解<span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Libraries&nbsp;</span><span>（库）的定义<span>:&nbsp;</span>它是一个例程的集合<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Libraries&nbsp;</span><span>（库）的形式<span>:&nbsp;</span>像单元文件一样<span>,&nbsp;</span>&#8220;动态链接库<span>&#8221;</span>包含共享的代码和资源<span>,</span>但这个库是一个可以单独编译的可执行文件<span>,</span>它在运行时被连接到使用它的程序当中<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>调用动态链接库<span>:</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><span>&nbsp;&nbsp;&nbsp;</span></span><span>在<span>Delphi&nbsp;</span>当中<span>&nbsp;Windows&nbsp;</span>系统例程<span>(Windows API)&nbsp;</span>存放在<span>Uses&nbsp;</span>的子单元当中<span>.</span>事先就给开发者们把<span>API</span>函数连接到了<span>Delphi</span>的系统单元文件当中<span>(</span>系统单元是不可见的<span>).</span>方便调用<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>你可以直接调用操作系统的例程<span>,</span>但他们直到运行时才被连接到你的程序当中<span>.</span>这说明在编译程序时它们不会被编译验证<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>这也说明当你调入一个&#8220;动态链接库<span>&#8221;</span>中的例程是不会被编译验证的<span>.</span>当你调用外部&#8220;动态链接库<span>&#8221;,</span>如果&#8220;动态链接库<span>&#8221;</span>没有相应的例程则会出现无法定位而报错<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>调用动态链接库有两种调用方法<span>: 1.</span>静态调入<span>&nbsp;2.</span>动态调入<span></span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>1.</span><span>静态调入</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>使用<span>&nbsp;external&nbsp;</span>指示字声明<span>&#8221;</span>动态链接库<span>&#8221;</span>名称<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在<span>&nbsp;Windows&nbsp;</span>下：<span>&nbsp;procedure DoSomething; external 'MYLIB.DLL';</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在<span>&nbsp;Linux&nbsp;</span>下：&nbsp;<span><span>&nbsp;&nbsp;</span>&nbsp;procedure DoSomething; external 'mylib.so'; &nbsp;</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>需要注意的有<span>:</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>1.MyLIB.DLL&nbsp;</span><span>或者<span>&nbsp;mylib.so&nbsp;</span>这<span>2</span>个文件必须在程序的根目录下才能顺利调入<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>2.</span><span>例程名也必须与&#8220;动态链接库<span>&#8221;</span>当中的例程名相同才能顺利的调入<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>若你在程序中包含这个声明，&#8220;动态掉入库<span>&#8221;</span>在程序启动时被调入一次<span>,</span><u>在程序的整个运行期间，标志符<span>&nbsp;DoSomething&nbsp;</span>总是指同一个共享库中的同一个入口点。</u></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><u><span>静态调入的缺点<span>:</span>例程占用内存<span>,&nbsp;</span>直到程序结束<span>.</span></span></u></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>2.</span><span>动态调入</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>动态调入就是利用操作系统中的库函数<span>(API</span>函数<span>)</span>来调入一个外部</span><span>&#8220;</span><span>动态链接库<span>&#8221;</span>中的例程<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>通常我们使用<span>&nbsp;LoadLibrary,FreeLibrary,GetProcAddress.&nbsp;</span>这<span>3</span>个函数来动态调用一个外部的&#8220;动态链接库<span>&#8221;</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>{</span><span>这<span>3</span>个函数的使用方法我已经详细的写在了博客当中<span>.</span>连接地址为<span>:</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><a href="http://www.cnitblog.com/Archer/archive/2009/03/28/55831.html" style="font-weight: bold; color: rgb(0, 107, 173); text-decoration: none; ">http://www.cnitblog.com/Archer/archive/2009/03/28/55831.html</a></span><span>}</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><u><span>动态调入的优点<span>:</span>解决了静态调用时<span>,</span>例程占用内存的问题<span>.</span></span></u></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Writing dynamically loadable libraries</span><span>（编写动态调入库）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Writing dynamically loadable libraries</span><span>（编写动态调入库）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span><span>&nbsp;&nbsp;&nbsp;</span>&#8220;</span><span>动态链接库<span>&#8221;</span>与程序文件唯一不同的就是<span>:&nbsp;</span>以关键字<span>Library&nbsp;</span>开始<span>.</span>取代了<span>(program).</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>编写动态链接库需要注意以下几点<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><u><span>1.</span></u><u><span>只有被库明确输出<span>(exports)</span>的例程才能被其他库或程序导入</span></u><span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><u><span>2.</span><span>&nbsp;</span></u><u><span>若要你的库对其它语言编写的程序是可见的，最安全的办法是在声明输出函数时指定&nbsp;<span>stdcal</span><span>&nbsp;</span>调用约定，其它语言或许不支持<span>&nbsp;Object Pascal&nbsp;</span>默认的<span>&nbsp;register</span>调用约定</span></u><span>。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>库的源文件通常简化为包含一个<span>&nbsp;uses&nbsp;</span>子句、一个<span>&nbsp;exports&nbsp;</span>子句和初始化代码<span>(</span>指的是过程和函数的<span>block</span>代码<span>)</span>。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>The exports clause</span><span>（<span>exports&nbsp;</span>子句）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>当一个例程在<span>&nbsp;exports</span>子句中列出时，它将被输出<span>,</span>才能被其他库或程序 导入<span>,</span>调用<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>exports entry1, ..., entryn;</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>每个<span>&nbsp;entry</span>可以是一个过程、函数或变量（它必须在<span>&nbsp;exports&nbsp;</span>子句之前声明）的名称，后面跟参数列表（只有当输出重载的例程时）和一个可选的<span>&nbsp;name&nbsp;</span>说明符，你可以使用单元名限定过程或函数的名称。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>需要注意的有<span>:</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>1.&nbsp;</span><span>&#8220;动态链接库<span>&#8221;</span>输出例程建立不要使用索引说明符<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>2.&nbsp;</span><span>名称说明符包括指示字<span>name&nbsp;</span>后面跟一个<u>字符串常量</u><span>.</span></span><span>&nbsp;</span><span>若<span>entry</span>没有名称说明符，例程被输出时使用声明的原始名称，包括拼写和大小写。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;exports</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;DoSomethingABC name 'DoSomething';</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>当在动态调入库中输出重载的函数或过程时，你必须在<span>&nbsp;exports&nbsp;</span>子句中指定它的参数列表，</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>exports</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;Divide(X, Y: Integer) name 'Divide_Ints',</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;Divide(X, Y: Real) name 'Divide_Reals';</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Library initialization code</span><span>（库初始化代码）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>一个库的块（<span>block</span>）所包含的语句构成了库的初始化代码，每当库被调入时，这些代码执行一次。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Global variables in a library</span><span>（库中的全局变量）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在库中声明的全局变量不能被<span>object Pascal&nbsp;</span>程序导入<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>一个库一次能被多个程序使用<span>(</span>调用<span>)</span>，每一个程序都把这个库加载到自己进程空间<span>(</span>内存空间<span>)</span>里<span>(</span>这是一个库的拷贝<span>),</span>且每个拷贝有自己的全局变量集合。对于在多个库间（或一个库的多个实例间）<span>共享内存，它们必须使用内存映射文件。</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>这里说明库是被加载到内存当中的<span>.</span>在内存中文件是以<span>16</span>进制定位内存地址的<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Libraries and system variables</span><span>（库和系统变量）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在<span>&nbsp;System</span>单元声明的几个变量对自己引入的程序库有特殊影响<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>1.IsLibrary&nbsp;</span><span>变量</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>IsLibrary</span><span>变量是在<span>System.pas</span>单元中定义的全局标志变量之一。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>使用<span>&nbsp;IsLibrary&nbsp;</span>变量来确定代码是作为<span>&lt;</span>程序<span>&gt;</span>还是<span>&lt;</span>库<span>&gt;</span>执行，<span>IsLibrary&nbsp;</span>在程序中总是&nbsp;<span>False</span>，在库中总是&nbsp;<span>True;</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>如果<span>IsLibrary</span>的值为<span>True</span>则表明程序模块<span>(</span>自身<span>)</span>是一个动态链接库，反之就是一个可执行程序。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;&nbsp;</span><span>此函数常用来判断调用的程序模块<span>(</span>自身<span>)</span>是&#8220;动态链接库&#8221;或者是&#8220;可执行程序&#8221;<span>.</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;2.</span><span>&nbsp;</span><span>Hinstance (Handle instance&nbsp;</span><span>句柄实例<span>)</span></span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>hinstance</span><span>是这个</span><span>&lt;</span><span>应用程序</span><span>&gt;</span><span>的</span><span>&lt;</span><span>实例句柄</span><span>&gt;</span><span>，也就是系统将可执行文件的映象加载到进程空间的基本地址，如果需要程序内包含的</span><span>&lt;</span><span>资源</span><span>(</span><span>如图片资源</span><span>)&gt;</span><span>的时候就需要这个实例句柄了。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>当你启动一个程序时，操作系统会给这个程序起一个名字，这个名字就叫</span><span>&nbsp;Handle</span><span>。</span><span><br></span><span>当你启动一个程序时，操作系统会将这个程序装载到某个内存空间，这个空间的起始地址就是</span><span>HInstance</span><span>。在</span><span>&nbsp;NT&nbsp;</span><span>系统这个</span><span>&nbsp;HInstance&nbsp;</span><span>一般都是</span><span>&nbsp;400000h</span><span>。</span></p><table cellspacing="0" cellpadding="0" width="589" border="1"><tbody><tr><td valign="top" width="589" style="font-size: 12px; "><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Handle</span><span>是</span><span>windows</span><span>系统里的句柄，是系统识别目标对象的一个标识，对于整个操作系统来说各句柄应该是唯一的，不会重复。而且</span><span>Handle</span><span>一般是由</span><span>Windows</span><span>系统分配的，程序无法控制。</span><span><br></span><span>而</span><span>HInstance&nbsp;</span><span>是程序内部的句柄，实际值即</span><span>Windows</span><span>系统给应用程序分配的内存基址，也是该程序体内（包括主体</span><span>EXE</span><span>和调用的</span><span>DLL</span><span>）相互识别调用的一个标识，对于程序内部来书说，</span><span>HInstance</span><span>是唯一的，不会重复。但对于</span><span>Windows</span><span>系统来说，各程序</span><span>EXE</span><span>的</span><span>HInstance</span><span>大部分可以说是一样，一般都是默认的</span><span>$00400000</span><span>。这个值在大多数编译器中都可以修改。如</span><span>DELPHI</span><span>里可以在工程</span><span>Options-&gt;Link-&gt;ImageBase</span><span>里修改。</span><span><br></span><span>简单来说，大概应该可以这样来理解，</span><span>Handle</span><span>可以说是</span><span>Windows</span><span>对象句柄，</span><span>HInstance</span><span>可以说是程序模块句柄。</span>&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p></td></tr></tbody></table><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>参考</span><span>:</span><span>&nbsp;{</span><span>http://www.delphibbs.com/delphibbs/dispq.asp?lid=3136263}</span></p><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>3.</span><span>&nbsp;</span><span>DLLProc</span></p><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;DLLProc&nbsp;</span><span>变量允许一个库监测</span><span>(</span><span>监视</span><span>)</span><span>操作系统对它的入口点（</span><span>entry point</span><span>）的调用，这个特征通常只是由支持</span><span>&lt;</span><span>多线程</span><span>&gt;</span><span>的库使用。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在过程体中，你能依据哪个参数被传递给过程来指定要采取地行动。</span></p><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>要监测操作系统调用，创建一个回调过程，它接收一个整数参数，</span><span></span></p><p align="left" style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>此函数有以下几个参数</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>　</span><span>&nbsp;<span>DLL_Process_Attach:&nbsp; //</span></span><span>整个</span><span>DLL</span><span>的初始化代码</span><span>&nbsp;<br></span><span>　</span><span>&nbsp;<span>DLL_Process_Detach:&nbsp; //</span></span><span>该值表示库作为完全退出的结果或调用</span><em><span>FreeLibrary</span></em><span>的结果，从调用库的进程中被分离。</span><span>&nbsp;{</span><span>表示对</span><span>DLL</span><span>的善后代码</span><span>}</span><span>&nbsp;<br></span><span>　</span><span>&nbsp;<span>DLL_Thread_Attach:&nbsp; //</span></span><span>该值表示当前进程创建了一个新的线程（仅适用于</span><span>Windows</span><span>）。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>　</span><span>&nbsp;<span>DLL_Thread_Detach: &nbsp;//</span></span><span>该值表示线程完全退出（仅适用于</span><span>Windows</span><span>）</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Exceptions and runtime errors in libraries</span><span>（库的异常和运行时错误）</span><span>&nbsp;</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>当在动态链接库中有发生异常</span><span>,&lt;</span><span>但没有处理时</span><span>&gt;,</span><span>它把异常传播到库的外面到达调用者</span><span>.</span><span>则出现错误提示</span><span>,</span><span>导致程序结束</span><span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>&nbsp;</span><span>如果调用程序或库是用</span><span>&nbsp;object Pascal&nbsp;</span><span>编写的</span><span>.&nbsp;</span><span>可通过用</span><span>tey...except&nbsp;</span><span>语句处理这些异常</span><span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>如果调用程序或库是用其它语言编写的，异常被当作操作系统的异常（异常代码：</span><span>$0EEDFACE</span><span>）进行处理。在操作系统异常记录的</span><span>&nbsp;ExceptionInformation&nbsp;</span><span>数组的第一个入口中，包含了异常地址，第二个入口包含一个指向</span><span>&nbsp;Object Pascal&nbsp;</span><span>异常对象的引用。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>通常，你不应该使异常扩散到库的外面。在</span><span>&nbsp;Windows&nbsp;</span><span>下，</span><span>Delphi&nbsp;</span><span>异常映射到操作系统的异常模型</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>若一个库没有使用</span><span>&nbsp;SysUtils&nbsp;</span><span>单元，它不支持异常处理。</span><span>这种情况下，若库发生运行时错误，调用程序将终止。因为库没有办法知道它是否从一个</span><span>&nbsp;Object Pascal&nbsp;</span><span>程序进行调用，它不能调用程序的退出过程，程序只是简单地被终止，并从内存中清除。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>Shared-memory manager (</span><span>共享内存管理器</span><span>)</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>当使用</span><span>Delphi&nbsp;</span><span>自带的内存管理器时</span><span>:</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>在</span><span>Windows&nbsp;</span><span>下</span><span>.&nbsp;</span><span>如果</span><span>DLL&nbsp;</span><span>输出的例程是长字符串或者动态数组作为参数或者作为函数返回值</span><span>(</span><span>不管是直接的</span><span>,</span><span>还是通过记录或对象封装的</span><span>),</span><span>那么</span><span>DLL&nbsp;</span><span>和它的客户端程序</span><span>(</span><span>或</span><span>DLL)</span><span>必须使用</span><span>ShareMem&nbsp;</span><span>单元</span><span>.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>(</span><span>由于库和程序之间内存管理的管理域限制</span><span>,</span><span>所以需要申请</span><span>ShareMem</span><span>单元</span><span>,</span><span>使他们能够共用一个内存管理器</span><span>)</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>当一个程序或</span><span>&nbsp;DLL&nbsp;</span><span>调用</span><span>&nbsp;New</span><span>或</span><span>&nbsp;GetMem</span><span>分配内存，而在另一个模块中调用</span><span>&nbsp;Dispose</span><span>或</span><span>&nbsp;FreeMem</span><span>来释放内存时。需要用到</span><span>ShareMem</span><span>单元</span><span>,.</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>ShareMem</span><span>单元应当在程序或库的</span><span>&nbsp;uses</span><span>子句中第一个列出。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>ShareMem&nbsp;</span><span>是</span><span>&nbsp;BORLANDMM.DLL&nbsp;</span><span>内存管理器的接口单元，它允许在模块间共享动态分配的内存。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>BORLANDMM.DLL</span><span>必须连同使用</span><span>ShareMem</span><span>单元的程序和</span><span>DLL</span><span>一同发布。</span><span>&nbsp;</span><span>当程序或</span><span>DLL</span><span>使用</span><span>ShareMem</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>时，它的内存管理器被</span><span>&nbsp;BORLANDMM.DLL&nbsp;</span><span>中的取代。</span></p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; ">&nbsp;</p><p style="font-size: small; color: rgb(0, 0, 0); padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; word-wrap: break-word; "><span>现在常用的内存管理器有</span><span>FastShareMem</span></p><br><br>为了方便阅读提供PFD版本:&nbsp;<a href="http://www.cnitblog.com/Files/Archer/Delphi%20library.zip" style="font-weight: bold; color: rgb(0, 107, 173); text-decoration: none; ">http://www.cnitblog.com/Files/Archer/Delphi%20library.zip</a></span>
<img src ="http://www.cnitblog.com/Archer/aggbug/56302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Archer/" target="_blank">Archer</a> 2009-04-13 11:20 <a href="http://www.cnitblog.com/Archer/archive/2009/04/13/56302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>