The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,830 other subscribers

Archive for the ‘Delphi’ Category

The intrinsic factory pattern that every Delphi programmer uses

Posted by jpluimers on 2020/01/22

A blast from the past: my 2009 answer to [WayBackWhat Design Patterns do you implement in common Delphi programming? – Stack Overflow which is still very much relevant today.

TL;DR

Every Delphi programmer uses the factory pattern as it is an intrinsic part of how components at design time work.

So he were go:

Only a minority of the Delphi developers knows that every Delphi developer uses a Factory pattern (delphi.about.com has an example in “regular” Delphi), but then implemented using virtual Create constructors.

So: time to shed some light on that :-)

Virtual constructors are to classes like virtual methods are like object instances.

The whole idea of the factory pattern is that you decouple the logic that determines what kind (in this case “class”) of thing (in this case “object instance”) to create from the actual creation.

It works like this using virtual Create constructors:

TComponent has a virtual Create constructor so, which can be overridden by any descending class:

type
  TComponent = class(TPersistent, ...)
    constructor Create(AOwner: TComponent); virtual;
    ...
  end;

For instance the TDirectoryListBox.Create constructor overrides it:

type
  TDirectoryListBox = class(...)
    constructor Create(AOwner: TComponent); override;
    ...
  end;

You can store a class reference (the class analogy to an object instance reference) in a variable of type ‘class type’. For component classes, there is a predefined type TComponentClass in the Classes unit:

type
  TComponentClass = class of TComponent;

When you have a variable (or parameter) of type TComponentClass, you can do polymorphic construction, which is very very similar to the factory pattern:

var
  ClassToCreate: TComponentClass;

...

procedure SomeMethodInSomeUnit;
begin
  ClassToCreate := TButton;
end;

...

procedure AnotherMethodInAnotherUnit;
var
  CreatedComponent: TComponent;
begin
  CreatedComponent := ClassToCreate.Create(Application);
  ...
end;

The Delphi RTL uses this for instance here:

Result := TComponentClass(FindClass(ReadStr)).Create(nil);

and here:

// create another instance of this kind of grid
SubGrid := TCustomDBGrid(TComponentClass(Self.ClassType).Create(Self));

The first use in the Delphi RTL is how the whole creation process works of forms, datamodules, frames and components that are being read from a DFM file.

The form (datamodule/frame/…) classes actually have a (published) list of components that are on the form (datamodule/frame/…). That list includes for each component the instance name and the class reference. When reading the DFM files, the Delphi RTL then:

  1. finds about the components instance name,
  2. uses that name to find the underlying class reference,
  3. then uses the class reference to dynamically create the correct object

A regular Delphi developer usually never sees that happen, but without it, the whole Delphi RAD experience would not exist.

Allen Bauer (the Chief Scientist at Embarcadero), wrote a short blogarticle about this topic as well. There is also a SO question about where virtual constructors are being used.

Let me know if that was enough light on the virtual Create constructor topic :-)

This resulted in this interesting comment by Kenneth Cochran:

Factory pattern implementations in other languages use ordinary static functions (or class functions for pascalites). As such they are capable of returning null(nil). A Delphi constructor, like the nameless constructors in other languages, will always return an object reference unless you raise an exception. You are free, of course, to use a class function just as easily if the need arises.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi, compiler intrinsics and generic type matching

Posted by jpluimers on 2020/01/21

For my link archive in case I ever need to do Delphi generic type matching on intrinsic types. This will be tricky as you can have typed types like [WayBacktype TDate = type TDateTime since the early Delphi ages.

[WayBack] Hi, by using compiler intrinsics, is it possible to check if a generic type parameter is an unsigned integer? – Malcon X Portela – Google+

It will probably come down to fast intrinsic type mapping and slower typed type mapping.

The above WayBack link contains the most important bits of the Google+ post:

Hi, by using compiler intrinsics, is it possible to check if a generic type parameter is an unsigned integer? I have the following code:

function TChecker<T>.CheckIsUnsigned: Boolean;
begin
  if GetTypeKind(T) = tkInteger then
  begin
  if SizeOf(T) = 4 then
  begin
    // TODO: Check if it is an unsigned 32-bit integer
    Result := True;
  end else if SizeOf(T) = 2 then
  begin
    // TODO: Check if it is an unsigned 16-bit integer
    Result := True;
  end else
  begin
    // TODO: Check if it is an unsigned 8-bit integer
    Result := True;
  end;
  end else
  begin
    Result := False;
  end;
end;

The code should return True only if the ‘T’ generic type parameter is an unsigned integer. I remember that +Stefan Glienke posted here some code that can do this trick, however, I am not able to find that now.

Thanks!


Hi +Jeroen Wiert Pluimers, my answer can be a bit disappointing, sorry :( Some time after writing this question here, I just realized which for the things I was originally trying to do, being signed or unsigned would not change anything on the final result hehehehe :D But from this amazing project https://github.com/d-mozulyov/Rapid.Generics (entire credits goes to Dmitry Mozulyov for the magic), it is possible to write the check to the generic type parameter in order to identify if it is a 32-bit/64-bit signed or unsigned number.

LTypeData := PTypeInfo(TypeInfo(T)).TypeData;

case GetTypeKind(T) of
  tkInteger:
  begin
    {case LTypeData.OrdType of
      otSLong: Writeln('32-bit signed');
      otULong: Writeln('32-bit unsigned');
    end;}
    // the above code does the same thing
    if LTypeData.MaxValue > LTypeData.MinValue then
    begin
      Writeln('32-bit signed');
    end else
    begin
      Writeln('32-bit unsigned');
    end;
  end;
  tkInt64:
  begin
    if LTypeData.MaxInt64Value > LTypeData.MinInt64Value then
    begin
      Writeln('64-bit signed');
    end else
    begin
      Writeln('64-bit unsigned');
    end;
  end;
end;

The [WayBack] Rapid.Generics project is indeed cool, but unmaintained and has no unit tests. The main code is in some [Wayback] 30k lines Rapid.Generics.pas unit with some cool ideas and implementations. Hopefully people will find time to integrate some of the ideas there into basically the only well maintained Delphi generics library Spring4D.

A big limitation might be that the code is Delphi XE8 and up only, whereas Spring4D supports older Delphi versions.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Delphi: A few notes on tracking down a use-after free related issue involving interfaces crashing inside System._IntfClear.

Posted by jpluimers on 2020/01/20

A few notes on tracking down a use-after free related issue involving interfaces.

The crash message is like this:

Project UseAfterFreeWithInterface.exe raised exception class $C0000005 with message 'access violation at 0x004106c0: read of address 0x80808088'.

Two things here:

An important note first

Basically any memory value in an exception starting with $8080 and sometimes even $80 should raise suspicion: it usually means a use-after-free case.

You see these errors with FastMM and not with the memory manager as [WayBack] delphi • View topic • Problem with FastMM and D7 explains:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 8 Comments »

Tweaking4All.com – Topics – Delphi – How to change the font of a hint window

Posted by jpluimers on 2020/01/19

[WayBack] Tweaking4All.com – Topics – Delphi – How to change the font of a hint window: Delphi THintWindow are odd, as you cannot set the Vcl.Forms.HintWindowClass before uses it to initialise the hint window in the Application instance from the initialisation section in the Vcl.Forms unit.

The only way to change it is to:

  1. Set the HintWindowClass to a new class
  2. Toggle the state of Application.ShowHint

So the duplicate line below is no accident:

  HintWindowClass := TMyHintWindow;
  Application.ShowHint := not Application.ShowHint;
  Application.ShowHint := not Application.ShowHint;

References:

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Drawbacks for separating TDS/TD32 symbol information in separate file for your Delphi applications? What about Visual Studio?

Posted by jpluimers on 2020/01/15

A while ago this interesting question came by: [WayBack] Delphi XE2 has got the Linking option “Place debug information in separate TDS file” … Does this have any adverse effects for Win32 Delphi executables? – Thomas Mueller (dummzeuch) – Google+

The answer is “no”.

By about mid 2018, the same holds for Visual Studio and PDB symbol information.

Delphi

Since long ago (I think about Delphi 2), the Delphi debugger understands TDS (historically also known as TD32) Turbo Debugger Symbol Information which can be either in the .EXE or in a separate .TDS file with the same name and directory as the .EXE.

Many other tools also know how to get the symbols from either place, see for instance TD32-TDS-SYMBOL-INFORMATION.

The advantage of keeping it in the EXE is that it is easier to ship to clients. Unless you do not want the clients to have it. Then it is easier to separate it in a file.

David Heffernan raises an important point though, as many people confuse these two topics:

  • the presence of Debug Symbols
  • the code generation of extra run-time checks and debug-assistance (like stack frames)

This is caused by both of the above usually being enabled in DEBUG mode and disabled in RELEASE mode.

However, nothing prevents you from generating the Debug Symbols in RELEASE mode, and they can highly help track down customer problems.

This is David’s comment:

There’s a common myth that “debug builds” perform worse than “release builds”.

Whether or not debug information is generated is completely independent from the performance of the code.

Visual Studio

For a long time, EXE files generated by Microsoft Tools could only include .DBG symbol information, but no .PDB symbol information.

[WayBack] executable – Embed .pdb debug symbol information into an .exe file in Visual Studio – Stack Overflow. Especially read the comments about:

–jeroen

Posted in Debugging, Delphi, Development, MAP Symbol Information, Software Development, TD32/TDS Symbol information | Leave a Comment »

Delphi Datasnap: How to know the name of the methods called by client in delphi datasnap server?

Posted by jpluimers on 2020/01/14

A great tip from [WayBack] Hi, need help regarding Datasnap. How to know the name of the methods called by client in delphi datasnap server? – sujansiddhi – Google+ that I needed a few months ago:

Walter Prins:

Inside TDSAuthenticationManager.OnUserAuthorize, inspect the EventObject.MethodAlias property. (Obviously once the method is actually called you implicitly know the methodname.)

This was introduced in Delphi XE:

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Getting the up to date project source code from the IDE – Dave’s Development Blog

Posted by jpluimers on 2020/01/09

For my link archive: [WayBackGetting the up to date project source code from the IDE – Dave’s Development Blog

It shows how to “using the IDE’s live files and if the IDE hasn’t got a file open, the file from disk”.

This gives you the same view the compiler in the IDE has.

Via [WayBack] Getting the up to date project source code from the IDE – David Hoyle – Google+

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

TFreedObject in FastMM4/FastMM4.pas at master · pleriche/FastMM4 · GitHub

Posted by jpluimers on 2020/01/08

Reminder to Self:

  {The class used to catch attempts to execute a virtual method of a freed
   object}
  TFreedObject = class
  public
    procedure GetVirtualMethodIndex;
    procedure VirtualMethodError;
{$ifdef CatchUseOfFreedInterfaces}
    procedure InterfaceError;
{$endif}
  end;

If you encounter the class TFreedObject when doing a cast, then you’re working on a freed object and have FastMM4 enabled to detect that.

Source: [WayBackFastMM4/FastMM4.pas at master · pleriche/FastMM4 · GitHub; FastMM4 – A memory manager for Delphi and C++ Builder with powerful debugging facilities

Note that if you want to see the underlying FastMM data for any TObject allocation, use this watch (where Self is the current instance):

PFullDebugBlockHeader(PByte(Self) - SizeOf(TFullDebugBlockHeader))^

You can also put a ,r behind it to see the fields of this structure:

(Reserved1:nil; Reserved2:nil; AllocatedByRoutine:$41BF74; AllocationGroup:0; 
AllocationNumber:592682; 
AllocationStackTrace:(4224198, 4233131, 4235210, 11103806, 6552132, 131126, 6597961, 11106984, 4235210, 11107153, 11104090); 
AllocatedByThread:90428; FreedByThread:90428; 
FreeStackTrace:(4241541, 131126, 4235210, 11103806, 6552132, 131126, 6597961, 11106984, 4235210, 11107153, 11104090); 
UserSize:36; PreviouslyUsedByClass:132272; HeaderCheckSum:2673350594)

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

VCL FadingEffect by Paul Toth at GitHub

Posted by jpluimers on 2020/01/07

In case I ever need a fading effect between 2 panels on one form, there is some code that will get me started.

I’d probably code it in a different design (without a global variable), but it works so can be a good source of ideas.

Source: Delphi/FadingEffect at master · tothpaul/Delphi · GitHub

Via: [WayBack] VCL Tiny demo of a Fading effect for Delphi Tokyo  – Paul TOTH – Google+

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, Software Development | Leave a Comment »

Im memoriam: Rudy Velthuis

Posted by jpluimers on 2020/01/05

Given that I’m fighting rectal cancer and am extremely low on energy, I am keeping this much shorter than I want to.

Recently, I learned that Rudy Velthuis passed away on 2019-05-13. Born on 1960-10-30, he passed away at only age 58.

After asking permission from his family, I wrote a small im memoriam.

We frequently encountered each other on-line in the Delphi community, especially in the early days when I was way more active on forums, newsgroups and chat channels. He was famous there, with good reason.

Though colloquially known as [WayBack“dentist with a strong interest in programming”, he was a great Delphi programmer and very well known for thoroughly documenting the many gaps that Embarcadero left in their documentation.

In 2009, Edwin van der Kraan and I had an opportunity to have dinner with Rudy. We met at his house, where we learned he not only ran a fully fledged dentistry practice, but also was married someone who origilally was from the Philippines. A truly happy couple they were.

In retrospect, I wish we had had met in real life more often, but I’m learning the hard way that life is finite giving you only so much time to do things.

I will remember Rudy because of his knowledge, wit and odd – but great – combination of work and interests.

In the mean time, I have asked a few archival organisations (including the WayBack machine) to archive his sites:

Some of his profiles that I archived on 20190103:

I love the “Kraftwerk – Autobahn” picture on his Stack Overflow profile page, so I included that song below the fold.

Related:

–jeroen

Read the rest of this entry »

Posted in About, Delphi, Development, History, Personal, Software Development | 4 Comments »