首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

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

2012-03-05 
主程序和DLL之间的全局变量问题(再线等!!)多次执行TUser.create后,为什么全局变量UserName会变化。下面是代

主程序和DLL之间的全局变量问题(再线等!!)
多次执行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.

[解决办法]
尽量不使用全局变量,如必须使用全局变量则必须加前缀 '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;
别处看的``我是个菜鸟 `不知道对你有帮助没

热点排行