主程序和DLL之间的全局变量问题(再线等!!)

大强快跑 2007-02-27 04:31:03
多次执行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;

interface

uses
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;

interface

uses
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;

interface

uses
Classes;

type
IUser = Interface(IInterface)

end;

implementation

end.
...全文
282 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
大强快跑 2007-02-27
  • 打赏
  • 举报
回复
哦,还有objUser: IUser;改为全局变量
大强快跑 2007-02-27
  • 打赏
  • 举报
回复
自己顶,刚刚调试了出来,作如下修改问题消失:
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;
yousiyong 2007-02-27
  • 打赏
  • 举报
回复
尽量不使用全局变量,如必须使用全局变量则必须加前缀'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;
别处看的``我是个菜鸟 `不知道对你有帮助没

16,742

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧