views:

133

answers:

3

In a delphi unit, I have a global record called 'Context':

interface
  type
    TContext = record
       ...
    end;

  var
    context: TContext;

I also have a initialization procedure in this unit, taking a context:

interface  
  procedure Init(AContext: TContext);

Inside the Init procedure, I try to assign the given context to the global context:

implementation
  procedure Init(AContext: TContext);
  begin
    context := AContext;
  end;

For some reason, the global context remains empty after the assignment. Why is that? Declaring a local variable inside the procedure, and assigning to it works as expected.


What I should have mentioned, is that this unit lives in a dll, and the init procedure is called from the exe. Declaring a global record, or declaring several global strings makes no difference. The assigned values are lost.

regards,
-Vegar

+3  A: 

I guess you have to show a bit more code. With

unit Unit1;

interface

type
  TContext = record
    dummy: Integer;
  end;

var
  context: TContext;

procedure Init(AContext: TContext);

implementation

procedure Init(AContext: TContext);
begin
  context := AContext;
end;

end.

and

program Project1;

{$APPTYPE CONSOLE}

uses
  Unit1 in 'Unit1.pas';

procedure Test;
var
  c: TContext;
begin
  c.dummy := 666;
  Init(c);
end;

begin
  Test;
end.

I get the expected result, i.e. c and Unit1.context both contain 666 after executing Init(c); in Test.

Ulrich Gerhardt
I always find it hard to decide the right amount of code needed to illustrate a problem. Posting the complete picture are seldom an option.
Vegar
Ugh... obviosly, it should be 42, not 666! :D
Alexander
That's boring - *everybody* uses 42. :-)
Ulrich Gerhardt
A: 

Should you not change

procedure Init(AContext: TContext);

to

procedure Init(Var AContext: TContext);

DwrCymru
No, because he inside `Init` he *reads* from AContext. But `const` (instead of `var`) might be a good idea.
Ulrich Gerhardt
No. -----------
Andreas Rejbrand
He says he wants to change the global var context, but when using a local var it works
DwrCymru
Right. He says he wants to change the *global* variable, `context`. Don't you see in the code where the `AContext` parameter is used to assign a new value to the global `context` variable? The `AContext` parameter is not the problem.
Rob Kennedy
So maybe we need to see how the local Var is being assigned as this seems to work. Declaring the var parameter actually changes the "Pointer" (or memory location) to reflect the new value, none of the original values get changed.
DwrCymru
@Dwr: `Init` reads `context := AContext;`, **not** `AContext := context;`
Ulrich Gerhardt
Yes, so passing a Var would mean context points to AContext
DwrCymru
No! The assignment is a bitwise copy with or without the `var`. The difference is that with the `var` AContext were a reference to whatever was passed to Init. Without, it's a copy.
Ulrich Gerhardt
A: 

The error is found. Everything was kind of a mess really.... It turned out that the object responsible for calling the init-method existed twice, and the unit containing the global variable existed both inside the dll and the exe project. For some reason, one of the instances of the calling class manipulated the global variable inside the exe and the other the one inside the dll, and both the developer and the debugger where tripped to a halt...

The code is part of some old, messy legacy code which we are trying to break apart and clean up. We really start to get the hang of the 'breaking'-part...

Thanks for the responses, and sorry for wasting your time.

regards, -Vegar

Vegar