English 中文(简体)
Object crashing when in main program, but not when moved to unit
原标题:

I ve written a custom SDL GUI toolkit (source is on http://sourceforge.net/projects/lkgui/files/) and I m having an issue with an inherited object.

When the object is within the main program, the constructor isn t called hence the program doesn t properly initialise the object and it crashes after some commands (Specifically, TStartGameButton inherits from GUI_Canvas inherits from GUI_Element and anything that is not defined in GUI_Element crashes the program with an EAccessViolation). When the object is placed within a unit, this problem goes away.

I understand that I could just leave it in the unit, but it will lead to some ugly code that could hopefully be avoided.

Has anyone any idea why this might be happening and how I may avoid it?

最佳回答

Old-style Delphi objects have been broken since the release of Delphi 2, perhaps earlier. They do not do inheritance well when they have fields of compiler-managed types, such as string or dynamic arrays. There was a discussion about it in 2004 on comp.lang.pascal.delphi.misc. Here was the code to reproduce it:

type
  TBase = object
  public
    s: string;
  end;

  TDerived = object(TBase)
  end;

procedure test;
var
  obj: TDerived; //okay for TBase!
begin
  assert(obj.s =   ,  uninitialized dynamic variable );
end;

And in fact it s only OK for TBase by accident because of how the function s prologue code happens to be generated. Putting additional code in that function can make it crash anyway.

Indeed, it s exactly as you ve observed — old-style objects don t get initialized properly. Their string fields don t start out holding an empty string; instead, they hold garbage, and so it s not even possible to initialize them yourself without using something like FillChar.

This appears to be due to the variables being local variables. Unit-scope ("global") variables seem to work OK. Variables that are declared at unit scope but only used by the unit s initialization section, or at program scope and used only in the DPR file s main begin-end block, are treated by the compiler as local variables, so they re not set to all-bits-zero like their global counterparts. When you move your variable declaration to a unit but continue to use it in your DPR file, it s elevated to "global" status.

Your TGUI_Element type has a string member called DbgName, and it looks like that s the only string field you have in the type hierarchy. Take that out, or change it to ShortString, and I ll bet your crashes go away, at least temporarily.

问题回答

Why are you giving all objects individual named constructors instead of making them virtual?

  type   tx = object
                constructor init; virtual;
                end;
         txx = object(tx)
                   constructor init; virtual; // like override in Delphi classes.
                  end;

If you need a visual hierarchy to look at, have a look at Free Vision, it demonstrates nearly every facet of the TP object model

Oops apparantly virtual constructors are not possible in the TP model





相关问题
determining the character set to use

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta ...

Help with strange Delphi 5 IDE problems

Ok, I m going nuts here. For the last (almost) four years, I ve been putting up with some extremely bad behavior from my Delphi 5 IDE. Problems include: Seemingly random errors in coride50.bpl ...

How to write a Remote DataModule to run on a linux server?

i would like to know if there are any solution to do this. Does anyone? The big picture: I want to access data over the web, using my delphi thin clients. But i´would like to keep my server/service ...

How convert string to integer in Oxygene

In Delphi, there is a function StrToInt() that converts a string to an integer value; there is also IntToStr(), which does the reverse. These functions doesn t appear to be part of Oxygene, and I can ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签