以前学VB,调用dll中的函数必须静态申明再调用,delphi能实现动态调用吗?怎样实现?

解决方案 »

  1.   

    在Delphi中动态调用DLL
        动态调用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;
        大家已经看到了,这种动态调用技术很复杂,但只要修改参数,如修改LoadLibrary('Cpp.dll')中的DLL名称为'Delphi.dll'就可动态更改所调用的DLL。
    一、定义所要调用的函数或过程的类型。
        在上面的代码中我们定义了一个TIntFunc类型,这是对应我们将要调用的函数TestC的。在其他调用情况下也要做同样的定义工作。并且也要加上stdcall调用参数。
    二、释放所调用的DLL。
        我们用LoadLibrary动态的调用了一个DLL,但要记住必须在使用完后手动地用FreeLibrary将该DLL释放掉,否则该DLL将一直占用内存直到您退出Windows或关机为止。
        现在我们来评价一下两种调用DLL的方法的优缺点。静态方法实现简单,易于掌握并且一般来说稍微快一点,也更加安全可靠一些;但是静态方法不能灵活地在运行时装卸所需的DLL,而是在主程序开始运行时就装载指定的DLL直到程序结束时才释放该DLL,另外只有基于编译器和链接器的系统(如Delphi)才可以使用该方法。动态方法较好地解决了静态方法中存在的不足,可以方便地访问DLL中的函数和过程,甚至一些老版本DLL中新添加的函数或过程;但动态方法难以完全掌握,使用时因为不同的函数或过程要定义很多很复杂的类型和调用方法。对于初学者,笔者建议您使用静态方法,待熟练后再使用动态调用方法。
      

  2.   

    先抢了一楼,当然是动态调用好:
    动态调用更灵活,更节省内存,虽然要稍慢一点,但谁会在乎呢?var
      MyFun:Function(i:integer):integer;//定义函数指针
      dllHandle:HMODULE;//dll的handle
      dllName:PChar;
    begin
      dllName:='d:\test\mydll.dll';
      dllHandle:=LoadLibrary(dllName);//装入dll到内存
      @MyFun:=GetProcAddress(dllHandle,'dllFun');//将过程类型转换为Pointer,获得dllFun地址
      MyFun(100);//调用函数
      .....
      FreeLibrary(dllHandle);//释放dll所占内存
    end;
    你看动态调用可以即用即消,甚至可在运行时再决定装载什么样的dll
      

  3.   

    静态调用的时候,在程序启动时如果找不到dll,会报个错,动态调用,要到调用的时候,才报错。这是其中一个。