上贴请看:
http://expert.csdn.net/Expert/topic/1420/1420601.xml?temp=.4657099
我是想问:(1)当我定义一个接口单元如下时,程序退出时是否要自己去释放prjDll?
unit ShareDll;function GetResult(AppHandle: THandle): TDataSet; stdcall;
//(2)我这里是否要定义一个过程:负责释放GetResult得到的TDataSet。如下
procedure ReleaseResult; stdcall;  //
implementationfunction GetResult; external 'prjDll' name 'GetResult';
procedure ReleaseResult; external 'prjDll' name 'ReleaseResult';//
end.
(3)当Dll中包含数据模块或窗体时,Dll的接口函数是否得定义在相关得单元里面?
(4)隐式和显示调用时,有没有性能得区别:比如说占有内存?
谢谢!!!

解决方案 »

  1.   

    (1)要想你的程序有着稳定性和高性能性,这一点应该要做。因为如果在程序退出后不释放一些内存的话,你的程序运行几次后,你的整个操作系统就会由于内存不够而面临崩溃,你必须要重新启动你的操作系统才可以恢复。所以在程序退出后记住释放prjDll或其它创建了但没有释放的资源。
    (2)最好能这样来做,保证你程序的性能和稳定性,原因同上。
    (3)可以,但在其它单元里面里记住写下这句话:exports 函数名。
    (4)隐式和显示的区别是一个静态,另处一个是动态,也就是说function GetResult; external 'prjDll' name 'GetResult';是静态链接库而LoadLibrary的方式是动态链接。静态链接是指编译器反对函数或过程的调用编译到可执行的代码中的方法,它的函数地址和内存中的应用程序地址相关。这种做法的好处就是程序退出后自动释放内存地址,不用手动来释放。这种做法的不好之处就是每次修改DLL里的内容,调用这个DLL的函数的应用程序都必须要再编译一次,这种做法在一些标准性的软件和发行出街的软件会避免使用,因为每次升级DLL,连整个应用程都可打包给用户。动态链接只有在运行的时候才引用外部的DLL函数,把函数的调用和函数的执行代码链接起来,这种做法的不好之处就是每次退出后要手动编写代码来释放内存地址,这种做法的好处就是每次修改DLL函数时,调用这个DLL函数的应用程序不用再重新编译,这种做法会最流行的应用在发行出街后多用户使用的软件中,因为它方便升级。
      

  2.   

    To Wally_wu(不想再写代码):
    (1)你在第四点的描述:程序中隐式调用prjDll时不用另写代码释放它,因为应用程序会自动释放内存地址?
    (3)//可以,但在其它单元里面里记住写下这句话:exports 函数名。
    这句不明白?
    如果说:我的Dll里面有窗体ShowForm,我在另一个单元中建立函数如下
    uses ShowFrm;
    function ShowDllForm(AHandle: THandle): longint; stdcall;
    implementation
    function ShowDllForm(AHandle: THandle): longint; 
    var
      ShowForm: TShowForm;
    begin
      try
        Application.Handle:= AHandle;
        ShowForm:= TShowForm.Create(Application);  
        Result:= Longint(ShowForm);
        ShowForm.ShowModal;
      finally
        ShowForm.Free;
      end;
    end;
    这个接口函数应该无需 exports 吧,直接列在工程的exports中就行?
    请问在同一个Dll工程中,函数得使用情况是否与project中一样?
    (4)如果隐式调用Dll,那倒不如把单元直接加入到应用程序工程里面去(当然是无需考虑exe文件的大小)?
    这样子的话,隐式调用Dll是否充当分离、封装project应用程序的方法?
      

  3.   

    (3)动态链接库内部调用不用exports就可以,但动态链接库外部调用就必须要exports.
    (4)但如果你的项目的规模很大时,何以通过DLL的原理来将你的项目来进行分割,始终一个人的能力有限。
    隐式调用Dll是否充当分离、封装project应用程序的方法?何以这样来说,但可看你是如何定义
      

  4.   

    To Wally_wu(不想再写代码):
    (1)程序中隐式调用prjDll时不用另写代码释放它,因为应用程序会自动释放内存地址???隐式调用Dll时,我觉得Dll主要提供隐藏实现细节的功能!?如果我的程序有 3 个Dll,其中 2 个里面多个函数(经常被调用),请问这种情况下,我要采用调用Dll的那种方式(显示或隐式)?
    要考虑到性能方面的问题
      

  5.   

    Reply:(1)程序中隐式调用prjDll时不用另写代码释放它,因为应用程序会自动释放内存地址???隐式调用Dll时,我觉得Dll主要提供隐藏实现细节的功能!?如果我的程序有 3 个Dll,其中 2 个里面多个函数(经常被调用),请问这种情况下,我要采用调用Dll的那种方式(显示或隐式)?
    要考虑到性能方面的问题--------------------------------------------------------------------
    (1)隐式调用是不用另写代码释放这个Dll,因为隐式调用DLL的函数就好象是使用主程序内部的其它函数一样,是不用另写代码来释放内存的。
    隐式调用Dll时,我觉得Dll主要提供隐藏实现细节的功能!?隐藏实现细节?很深的词的表达,我的语文水平不是很好,不太明白你的意思!隐式调用Dll实际上就是将DLL里的函数在主程序编译后(不是运行),分配主程序会调用的DLL的函数的内存地址给主程序。如果我的程序有 3 个Dll,其中 2 个里面多个函数(经常被调用),请问这种情况下,我要采用调用Dll的那种方式(显示或隐式)?要考虑到性能方面的问题
    两种做法在运行调用的函数在速度上没什么大的区别,但如果主程序调用的DLL的函数不多的话,显式做法会更耗内存。
    如果是项目软件,因为是单一来开发的,所以不需考虑升级的麻烦,所以我觉得使用隐式会方便点。
    但如果是发行出市场的应用软件,因为使用的User可以会很多,需要考虑到升级和维护的麻烦,所以我觉得使用显式会合理点,在主应用程中可以显式调用DLL,但Dll和Dll之间可以通过隐式调用。你问到软件工程和系统分析的问题啦!这些问题要花很多口水才可以说清楚。你的分好难拿呀,嘻嘻!
      

  6.   

    ^-^呵呵,非常感谢 Wally_wu(不想再写代码)!!!
    我还没想到:Dll和Dll之间可以通过隐式调用。
    这种情况是否与应用程序和Dll之间的调用(包含动态调用)一样,没区别吧?这个问题解决了就可以结贴了。我会另开一贴给你加分的。谢谢!!!
      

  7.   

    隐藏实现细节:这个是我看书得来的。里面是用来说明为什么使用Dll的。
      

  8.   

    Dll和Dll之间可以通过隐式调用,这种情况与应用程序和Dll之间的调用(包含动态调用)的原理是一样的,不过我还是建议使用动态调用的层次不要太深,比如:程序A动态调用DLLB,而DLLB又动态调用DLLC,这样会降低程序的性能和可读性,应该尽可以在一个层次上完成。
      

  9.   

    Advice:
    留意一下Boland公司的Package,它和DLL有相同的原理,如果你是使用Delphi的话,开发会方便得多。
      

  10.   

    TO:Wally_wu(不想再写代码) 
        老兄说了很多问题,是非常的热心呀!
        但很多东西都有错误哟:
    错误1:进程退出后,如果不自己释放动态加载的DLL(LoadLibrary),则会占用系统内存。
    错误2:静态引用的DLL会在主程序释放时自动释放,而动态应用的不会。
    错误3:修改静态引用DLL时,编译器会将该DLL函数或过程的调用编译到可执行的代码中,因此修改DLL源程序,也必须修改引用它的其他程序并重新编译和分发。
    错误4:动态引用DLL比静态引用的DLL更消耗内存。     哎,不想写再写代码也不要这样解释代码呀。李战.深圳