我编写了一个动态库文件,里面含有窗体,函数是:GetName(handle:THandle);
在主程序中,我直接调用该动态库里的函数GetName(application.handle),函数能够正常执行,函数中的窗体也能显示,但是关闭窗体时,主程序会提示非法操作。
同样是一个动态库函数,我在两个不同的主程序中运行,一个没有出错,另一个会有错误提示。不知道哪位老手碰到这样的问题。

解决方案 »

  1.   

    动态库程序:  
    procedure GetName(aHandle:THandle);
    begin
      //把应用程序的句柄赋给动态函数
      Application.Handle:=aHandle;
      //创建窗体
      testFrm:=TtestFrm.Create(Application);
      try
        testFrm.Showmodal;  finally
        testFrm.free;
      end;
    end;
    主程序:
    var
     getName:procedure(iHndle:THandle);stdcall;
      handle,i:integer;
    begin
      Handle := LoadLibrary('test.DLL');
      @getName:=GetProcAddress(Handle, 'GetName');
      if @getName<>nil then
         getName(Application.Handle);
    end;
    关闭这个testfrm窗体时就提示错误。
      

  2.   

    对不起现象描述错误,是都有错误提示,access violation at address 012E56F6 in module 'test.dll'.Read of address FFFFFFFF
      

  3.   

    建议在dll窗体的关闭事件里将窗体释放掉;
    procedure ttestform.close(sender: TObject);
    begin
      action := cafree;
      testform := nil;
    end;
      

  4.   

    用完后没有回复添加:Application.Handle := 0; //Restore it到
      try
        testFrm.Showmodal;  finally
        testFrm.free;
        Application.Handle := 0; //Restore it到
      end;
      

  5.   

    楼上的说得对,不要在finally直接free,
    testFrm.onClose:=ttestform.close
      

  6.   

    另外我分析,你这个程序之所以保错,是因为你调完这个函数之后,立即就退出了
    也没有freelibrary,dll退出比主程序晚,所以你调free的时候导致错误
      

  7.   

    procedure GetName(aHandle:THandle);
    var
      tmpfrm:TtestFrm;//使用这样局部变量减少出错机会。
    begin  Application.Handle:=aHandle;
      //创建窗体
      tmpfrm:=TtestFrm.Create(Application);
      try
        tmpFrm.Showmodal;  finally
    //    tmpFrm.free;
          tmpFrm.release;//释放FORM,用RELEASE比FREE好。
      end;....
      

  8.   

    begin
      Handle := LoadLibrary('test.DLL');
      try  
        @getName:=GetProcAddress(Handle, 'GetName');
          if @getName<>nil then
            getName(Application.Handle);
      finally
        freelibrary(handle);
      end;
    end;
      

  9.   

    感谢大家的支持,我已经找到原因了,动态库程序:  
    procedure GetName(aHandle:THandle);加上Stdcall;就不会错了,不小心漏了这个.不过大家提的意见也很正确.我以后要注意的.