接口:(DLL返回)
ITest = interface(IUnknown)
  function GetName: PChar;
end;TTest = (TInterfacedObject, ITest)
private
  FHandle: THandle;
public
  function Init(Handle: THandle): Boolean;
  function GetName: PChar;
  function GetHandle: THandle;
end;function TTest.Init(Handle: THandle): Boolean;
begin
  Result := True;
  FHandle := Handle;
end;function TTest.GetHandle: THandle;
begin
 Result := FHandle;
end;
接口列表:
  TRegisterDLL = function: ITest; stdcall;  TTestList = class
  private
    FList: TInterfaceList;
  public
    constructor Create;
    destructor Destroy; override;
    procedure LoadDLL(Filename: string);
    procedure UnloadDLL(Index: Integer);
  end;
//....
constructor TTestList.Create;
begin
  FList := TInterfacedList.Create;
end;destructor TTestList.Destroy;
begin
  while FList.Count > 0 do
    UnloadDLL(0);  FList.Free;
end;procedure TTestList.LoadDLL(FileName: string);
var
  LibHandle: THandle;
  Proc: TFarProc;
  Test: ITest;
begin
  LibHandle := LoadLibrary(PChar(FileName));
  //判断略
  Proc := GetProcAddress(LibHandle, 'RegisterDLL');
  Test := TRegisterDLL(Proc);
  Test.Init(LibHandle);
  FList.Add(Test);
end;procedure TTestList.UnloadDLL(Index: Integer);
var
  LibHandle: THandle;
begin
  LibHandle := (FList[Index] as ITest).GetHandle;
  FreeLibrary(LibHandle);
  FList.Delete(Index);
end;问题出在析构TTestList中,会出现地址访问错误。
单独使用UnloadDLL则不存在该问题
请教问题所在。

解决方案 »

  1.   

    问题应该出在这句:while FList.Count > 0 do
        UnloadDLL(0);
    改成:
    if FList.Count > 0 then
       UnloadDLL(0);
    就没问题了,不过可能与你想要执行的操作不一样了
      

  2.   

    重点检查一下 UnloadDLL 函数。看看在你执行时,对象是否还存在。不存在的对象操作,当然无可避免的,报地址访问错误.
      

  3.   

    //有点想不通, 如果上面的代码是楼主写的不应该出现这种错误.
    destructor TTestList.Destroy;
    var
      I: Integer
    begin
      for I :=  FList.Count-1 downto 0 do
        UnloadDLL(I);
      FList.Free;
      inherited;
    end;
      

  4.   

    while FList.Count > 0 do
      UnloadDLL(0)有错吗?你们有没有注意UnloadDLL过程里FList.Delete(Index);
    我做了删除了,FList的计数会减的,问题不是这里我这么问吧,如果我的DLL导出的是个接口,这个接口是从TInterfacedObject继承下来的
    当我FreeLibrary这个DLL的时候,我主程序中引用接口的那个变量是不是会自动释放。
      

  5.   

    你Destory没有 Inherited, 不能正确的释放资源.
      

  6.   

    to: cncharles(旺仔)
    我即时加上inherited也还是会出错的如果我的DLL导出的是个接口,这个接口是从TInterfacedObject继承下来的
    当我FreeLibrary这个DLL的时候,我主程序中引用接口的那个变量是不是会自动释放。
    这是问题。
      

  7.   

    举个例子说明一下var
      I: ITest;i := CreateDLL;CreateDLL是DLL里的导出函数返回ITest;
    当我卸载这个DLL后
    i 是不是会自动释放??
      

  8.   

    还有个问题就是DLL里那个接口是不是也回自动释放?