Search code examples
delphidlldelphi-2010

Delphi 2010 App loading a Delphi 7 DLL


My app is compiled with Delphi 2010. That app loads a Delphi 7 compiled DLL which loads a Delphi 2010 compiled DLL.

D2010 app LOADS D7 DLL LOADS D2010 DLL

The exported functions of the D7 DLL uses Widestrings and the exported functions of the Delphi 2010 DLL use strings.

As we all know, strings in Delphi 2010 are Unicode (2 bytes) and in Delphi 7 they are Ansi (1 byte).

All my tests show me that it is working despite the fact that it should not. I am wondering:

Why is it working?

What can go wrong?

Which memory manager should I use (Delphi 2010 or Delphi 7 memory manager DLL)


Solution

  • In D2009 and D2010, the RTL has logic in place (the compiler's {$STRINGCHECKS ON} directive) that allows an AnsiString to receive a Unicode payload, and a UnicodeString to receive an Ansi payload, across module boundaries, and then to perform a silent inline data conversion to the correct string type when the AnsiString/UnicodeString data is accessed. This is primarily to support legacy C++ projects that use event handlers with AnsiString parameters on the C++ side and UnicodeString variables on the Delphi side. In this case, it could also allow the D7 DLL to pass Ansi data to the D2010 DLL (the STRINGCHECKS directive was removed in XE, though).

    I would expect the D2010 DLL to fail, though, because the memory layout of a StrRec record (which preceeds the character data in memory) changed in D2009 to add support for codepages, so the D7 DLL would not be allocating a D2010-compatible StrRec when passing an AnsiString value to a UnicodeString parameter in the D2010 DLL. I would expect the D2010 DLL to crash when it tries to access/free memory that does not exist.

    This is yet another argument against ever passing String types across DLL boundaries. Just don't do it, ever. Use WideString or PAnsiChar/PWideChar instead.