多次执行TUser.create后,为什么全局变量UserName会变化。下面是代码:
主程序工程文件:
program Project1;uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  uUser in 'uUser.pas';{$R *.res}
function CurUserName: TUser;
begin
  Result := UserName;
end;procedure SetCurUserName(AUserName: TUser);
begin
  UserName := AUserName;
end;exports
  CurUserName, SetCurUserName;begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.主程序窗体:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uUser, StdCtrls, uIUser;type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    objUser: IUser;
  public
    { Public declarations }
  end;var
  Form1: TForm1;
  UserName: TUser;implementation
function TObjUser: IUser;
  external 'Project2.dll';
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
  objUser := TObjUser;
  Edit1.Text := UserName.FUserName;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
  objUser := nil;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
  objUser := TObjUser;
  Edit1.Text := UserName.FUserName;
end;end.Dll工程文件:
library Project2;{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }uses
  ShareMem,
  SysUtils,
  Classes,
  uUser in 'uUser.pas',
  uIUser in 'uIUser.pas';{$R *.res}
function TObjUser: IUser;
begin
  result := TUser.create;
end;exports
  TObjUser;begin
end.TUser类:
unit uUser;interfaceuses
  Windows, Forms, uIUser;type
  TUser = class(TInterfacedObject, IUser)
  private
    function CurUserName: TUser;
  public
    FUserName: string;
    constructor create;
    destructor Destroy;override;
  end;
  
implementation{ TUser }constructor TUser.create;
var
  SetCurUserName: procedure(AUserName: TUser);
begin
  FUserName := 'admin';
  if CurUserName = nil then
  begin
    @SetCurUserName :=
      GetProcAddress(GetModuleHandle(pchar(application.Exename)), 'SetCurUserName');
    SetCurUserName(Self);
  end;
end;function TUser.CurUserName: TUser;
var
  GetCurUserName: function: TUser;
begin
  @GetCurUserName :=
    GetProcAddress(GetModuleHandle(pchar(application.Exename)), 'CurUserName');
  //if Assigned(GetCurUserName) then //找到
  Result := GetCurUserName;
end;destructor TUser.Destroy;
begin  inherited;
end;end. IUser接口:
unit uIUser;interfaceuses
  Classes;type
  IUser = Interface(IInterface)  end;
  
implementationend.

解决方案 »

  1.   

    尽量不使用全局变量,如必须使用全局变量则必须加前缀'g',同时应在变量名称中体现变量的类型。例如: 
      gprecUserCount: point;//名称为UserCount的全局变量,其类型为指向一结构的指针 
    但是在模块内部可以使用全局变量。所有模块内全局变量必须用'F'为前缀。如果几个模块之间需要进行资料交换,则需要通过声明属性的方法来实现。例如: 
    type 
      TFormOverdraftReturn = class(TForm) 
      private 
    { Private declarations } 
    FuserName: string; 
    FuserCount: Integer; 
    Procedure SetUserName(Value: string); 
    Function GetUserName: string; 
      public 
    { Public declarations } 
    property UserName: string read GetUserName write SetUserName; 
    property UserCount: Integer read FuserCount write FuserCount; 
      end; 
      别处看的``我是个菜鸟 `不知道对你有帮助没
      

  2.   

    自己顶,刚刚调试了出来,作如下修改问题消失:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      objUser := TObjUser;
      Edit1.Text := UserName.FUserName;
      objUser := nil;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      //objUser := nil;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      objUser := TObjUser;
      Edit1.Text := UserName.FUserName;
      objUser := nil;
    end;
      

  3.   

    哦,还有objUser: IUser;改为全局变量