系统介绍:
1.中文 XP SP3
2.日文 XP SP3代码如下:
==========================DLL==========================uses
  Sharemem,
  SysUtils,
  Forms,
  Messages,
  Windows,
  Classes,
  ActiveX,
  comObj,
  untPRJ_1_Setup in 'untPRJ_1_Setup.pas' {frmPRJ_1_Setup},
  udmData in '..\Common\udmData.pas' {dmData: TDataModule},
  untCommon in '..\Common\untCommon.pas',
  AES in '..\Common\AES.pas',
  ElAES in '..\Common\ElAES.pas';{$R *.res}
var
  DllApp: TApplication;
   DLLScreen: TScreen;
  
   TheForm: TForm;
  TheClass: TPersistentClass;procedure RunDLL(DLLName, FormName, FormCaption: string;
  APP: TApplication; SC: TScreen) stdcall;
begin
  Application := App;
  Screen := SC;  RegisterClasses([TfrmPRJ_1_Setup]);  TheClass := GetClass('T' + FormName);  if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
  begin
    TheForm := TForm(TheClass.Create).Create(Application);    //TheForm := TfrmPRJ_1_Setup.Create(Application, FormCaption);
    //TheForm.Show;
    try
      TheForm.ShowModal;
    finally
      FreeAndNil(TheForm);
      //TheForm.Free;
    end;
  end;
end;procedure DLLUnloadProc(dwReason: Dword);
begin
  case dwReason of
  //DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH:
    //CoInitialize(nil);
    
  DLL_PROCESS_DETACH:    
  begin
    //CoUninitialize;   Application := DLLApp;                                                 
    Screen := DLLScreen;                                                    if TheForm <> nil then
      FreeAndNil(TheForm);                                 SendMessage(Application.Handle, WM_CLOSE, 0, 0);                        
    FreeLibrary(Application.Handle);                                            
  end;  DLL_THREAD_DETACH:
    //CoUninitialize;  end;
end; exports
  RunDLL;begin
  DLLApp := Application;                                                        
   DLLScreen := Screen;          DLLProc := @DLLUnloadProc;                                  
  DLLUnloadProc(DLL_PROCESS_ATTACH);
end.
==========================调用==========================
DPR文件
uses sharemem
type
  TRunDLL = procedure(DLLName, FormName, FormCaption: string;
    Application: TApplication; Screen: TScreen); stdcall;procedure TfrmMain.btnPRJ_1_SetupClick(Sender: TObject);
begin
  RunDLLForm('PRJ_1_Setup.dll', 'frmPRJ_1_Setup', 'ノ靹テ', Application, Screen);
end;procedure TfrmMain.RunDLLForm(DLLName, FormName, FormCaption: string;
  APP: TApplication; SC: TScreen) stdcall;
var
  GetDllHWND: HWND;
  RunDLL: TRunDLL;
begin
  GetDllHWND := LoadLibrary(PChar(DllName));
  if GetDllHWND = 0 then 
  begin
    MessageBox(0, PChar('テサモミユメオステ鉸ェ '+DLLName+' オトホトシ」ャヌ・キネマウフミヌキ・訒。'),
      'シモヤリDLLホトシハァーワ', MB_OK);
    Exit;
  end;
  
  try
    @RunDLL := GetProcAddress(GetDllHWND, 'RunDLL');                            
    if Assigned(@RunDLL) then
    begin
      try
        RunDLL(UpperCase(Trim(DLLName)), UpperCase(Trim(FormName)),
          FormCaption, APP, SC);      except
        raise Exception.Create('T' + FormName + 'イサエ贇レ」。');
      end;
    end;  finally
    FreeLibrary(GetDllHWND);
  end;
end; 
在中文下编译、运行没问题,编译后的文件拿到日文下、运行没问题。
如果在日文下,编译使用相同代码后,宿主程序在呼出DLL窗体时也没问题。
但是,当DLL窗体关闭后,再关闭宿主程序,delphi就会报内存错误和runtime error这是为什么捏?
在此BS下日文系统- -

解决方案 »

  1.   


    是不是DLL_PROCESS_DETACH: 里的这句
    FreeLibrary(Application.Handle); 
    出问题了
      

  2.   


    不是啊~F8一直可以运行到程序结束,之后稍等一会弹出access violation at 0x00404e0c: read of address 0x035c4960
      

  3.   

    你的delphi是支持unicode的delphi2010或更高版本么?
      

  4.   

    中文系统是D7
    日文系统是D7和D2010在日文下 不管用7还是2010 都报错
      

  5.   

    建议Lz试一下把string换成pchar再把我说的那句注释掉试试
      

  6.   

    哦对了另外 SendMessage(Application.Handle, WM_CLOSE, 0, 0);   这句我没看懂为什么要这么做,Application已经是dll自己的application了,而且外部程序也已经freelibrary了,dll窗体也关闭了为什么dll还要给自己发close消息呢?
      

  7.   


    感谢大家回复!我将string全部换成Pchar后也不行、SendMessage是我失误,复制时不小心把注释//删掉了。但是,我发现,静态调用DLL之后,就没问题了……
    我再试试看动态调用哪里出的问题!
    procedure RunDLL(DLLName, FormName, FormCaption: Pchar; APP: TApplication; SC: TScreen); stdcall; external 'PRJ_1_Setup.dll';procedure TForm1.Button1Click(Sender: TObject);
    begin
      //RunDLLForm(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
      RunDLL(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
    end;
      

  8.   


    procedure TForm1.Button1Click(Sender: TObject);
    begin
      RunDLLForm(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
      RunDLL(Pchar('PRJ_1_Setup.dll'), Pchar('frmPRJ_1_Setup'), Pchar(''), Application, Screen);
    end;
    还发现个有意思的地方
    先动态方法建立窗体 关闭
    再静态方法建立窗体 关闭
    最后关闭主程序
    不报错 一切正常……
      

  9.   

    自从上次来看回复之后,就没时间解决这个问题,直到昨天才想到,还有帖子没结...
    昨天的最新进展:
    library Setting;uses
      Sharemem,
      SysUtils,
      Forms,
      Messages,
      Windows,
      Classes,
      ActiveX,
      comObj,
      UntSetting in '..\Form\UntSetting.pas' { FrmSetting } ;
    {$R *.res}var
      DllApp: TApplication;
      DllScr: TScreen;
      TheForm: TForm;
      TheClass: TPersistentClass;procedure OpenMe(Parent: THandle; DllName, FrmName: string; App: TApplication;
      Scr: TScreen); stdcall;
    begin
      Application := App; //问题在这
      Screen := Scr;  RegisterClasses([TFrmSetting]);
      TheClass := GetClass('T' + FrmName);
      if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
      begin
        //Application.Handle := Parent;
        TheForm := TForm(TheClass.Create).Create(Application);
        try
          TheForm.ShowModal;
        finally
          FreeAndNil(TheForm);
        end;
      end;
    end;procedure DLLUnloadProc(dwReason: Dword);
    begin
      case dwReason of
        DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH:
          begin
            { 保存Dll初始的Application對象 }
            DllApp := Application;
            { 保存Dll初始的Screen對象 }
            DllScr := Screen;
            // CoInitialize(nil);
          end;    DLL_PROCESS_DETACH:
          begin
            { 還原Dll的Application對象 }
            Application := DllApp;
            { 還原Dll的Screen對象 }
            Screen := DllScr;        if TheForm <> nil then
              FreeAndNil(TheForm);        FreeLibrary(Application.Handle);        // CoUninitialize;
          end;    DLL_THREAD_DETACH:
          begin
            CoUninitialize;
          end;
      end;
    end;exports OpenMe;begin
      DllProc := @DLLUnloadProc;
      DLLUnloadProc(DLL_PROCESS_ATTACH);end.
    以上代码,在静态调用的时候没有问题
    动态调用后,关闭主程序会报run time error后来我尝试将Application := App;注释掉
    再将主窗体句柄传入DLL,如下:
    Application.Handle := Parent;
    动态,静态调用都没有问题很困惑啊...