IndySockets / Indy

Indy - Internet Direct
https://www.indyproject.org
434 stars 147 forks source link

EInvalidCast in Freepascal/Lazarus when -CR option is enabled #492

Closed rlebeau closed 11 months ago

rlebeau commented 11 months ago

If a user compiles Indy directly into a Freepascal/Lazarus project without installing it as a package, and if that project has the -CR compiler option enabled, then EInvalidCast errors can occur at runtime, such as inside of TIdThread.Cleanup(), for example.

See: https://forum.lazarus.freepascal.org/index.php/topic,63996.0.html Also: https://forum.lazarus.freepascal.org/index.php?topic=58944.msg486254#msg486254

This is because several areas of Indy use Delphi-style accessor classes to access protected class members across unit boundaries, but -CR can silently convert object hard-casts into the as operator, which obviously won't work for accessor classes as they require hard-casting to operate properly (since objects being casted don't derive from the accessor class itself).

Unknown whether -CR can be detected/disabled dynamically in code or not. If not, the only workaround I can think of is to re-engineer the affected areas of Indy to either 1) make protected members be public, or 2) use private interfaces to access the protected members.

rlebeau commented 11 months ago

Possible workaround - use FreePascal's {$objectChecks off} directive wherever Indy uses an accessor class, for example:

{$push}
{$objectChecks off}
LScheduler := TIdYarnOfThreadAccess(FYarn).FScheduler;
{$pop}