主程序
procedure Tmainform.message1Click(Sender: TObject);
var
  ShowForm:TShowDllForm;
begin
  DllHandle:=LoadLibrary('message32.dll');
  if DllHandle=0 then
  begin
    cm('无法装入DLL文件.');
    exit;
  end;
  @ShowForm:=GetProcAddress(dllhandle,'showdllform');
  //if not (@ShowForm=nil) then
  showform(pchar(application_username));
end;
//释放dll句柄
procedure Tmainform.FormDestroy(Sender: TObject);
begin
  if dllhandle<>0 then
  begin
    freelibrary(dllhandle); //释放dll句柄
  end;
end;
dllform
procedure showdllform({xhandle:Thandle;}str:pchar);    //str=登录名
begin
  //application.handle:=xhandle;
  if dllform=nil then
  begin
    dllform := Tdllform.Create(application);
  end;
  loginname:=str;//全局赋值 登录名
  dllform.show;
end;
procedure Tdllform.FormClose(Sender: TObject; var Action: TCloseAction);
var ThisMessage: String;
 dwThreadId: DWord;
 hThread: THandle;
begin
  idudpserver1.Active:=false;
  ThisMessage := label1.Caption+':'+inttostr(idudpserver1.defaultport)+','+loginname+',loginout';
  idudpclient1.Send(ThisMessage);
  idudpclient1.Free;
  idudpserver1.Free;  dllform.Free;
  dllform:=nil;
  //action:=cafree;
  hThread := CreateThread(nil, 0, @FreeLibrary, Pointer(HInstance), 0, dwThreadId);
  CloseHandle(hThread);
end;
用的是动态调用dll,先关闭dllfrom,在关闭主程序没有问题
要是直接关闭主程序的话,提示应用程序发生异常 未知的软件异常(0x0eedfade),位置为0x7c812aeb.

解决方案 »

  1.   

    在主窗體關閉前,將所有的子窗體先關閉。因為話比較多,這裏只是舉個例子Var 
      frmHandle : array of Thandle; // 每創建一個窗體,就把HANDLE放進來,釋放的時候要從裏面刪除
    在  Mainform.Onclosefor i :=   Application.MainForm.MDIChildCount -1  downto 0 do 
        Application.MainForm.MDIChildren[i].Free;for i := low(frmHandle) to high(frmHandle) do FreeLibrary(frmHanlde[i]);
      

  2.   

    还是没解决,我只有一个dll窗体
    用不着frmHandle : array of Thandle;这样吧?
    我直接在mainfrom onclose中
    FreeLibrary(dllhandle)
    结果dll窗体关闭后,主程序直接死掉了,没有任何提示
      

  3.   

    搞定了
    在dllform中再引出一个关闭窗体的接口freedllform在FreeLibrary(dllhandle)前执行一下freedllform,行了