Delphi - Unit x was compiled with a different version of x, when fixing a VCL bug
Asked Answered
H

3

3

I am using Delphi XE6 and using Datasnap and JSON in my project. There is a bug I want to correct in the VCL unit System.JSON.pas (in the TJSONString.ToString function) where it should be escaping backslash characters as well as quotes. In order to fix this I carried out the following :

  1. Copied System.JSON.pas from the standard VCL source folder to my project source folder
  2. Added System.JSON.pas to my project (using the newly copied file)
  3. Fixed the bug and attempted to compile

I get the error 'Unit Data.DBXCommon was compiled with a different version of System.JSON.TJSONObject'

I can see that the Data.DBXCommon unit references System.JSON, so I guess the compiler is now seeing 2 versions - my fixed version and the standard VCL version.

What is the correct way to implement VCL changes to avoid this problem?

Hopi answered 25/6, 2014 at 15:5 Comment(2)
IMO, it is always a good idea to rename such a unit. Only after that, you should add it to your project. This avoids such conflicts, but you may have to qualify some identifiers by unit name, if you do that. I usually copy the unit to my project directory, remove everything I don't need, sometimes even "use" the original unit, and even rename the classes I want to modify.Polyclinic
That achieves something else. The asker wants to fix a bug, presumably, so that other units, other RTL/VCL/FMX units, that use the unit to be fixed, pick up the fixed version.Messmate
M
2

There are two common reasons for this issue:

  1. You made changes to the interface section of the unit. You cannot do this without also re-compiling all units that use the unit you are modifying.
  2. You re-compile the unit with different compiler options from those used to build it originally. Deal with that by ensuring the compiler options used to compile the unit you modify are the same as used by Embarcadero. Typically Embarcadero compiles with default options. Impose these directly in the source file being modified, right at the very top of the file.

Having said this, a recent question here on a similar topic could not be resolved using option 2 above. In that question, under XE6 only, the unmodified Classes unit could not be re-compiled and linked at all. Which makes me wonder if this particular technique has had its day. Perhaps it's not even possible. Before you give up, see if you can compile and link the unmodified unit.

More broadly, using a detour is generally an easier way to solve such problems as you face. Using a detour rather than re-compiling makes the management of the fix cleaner and simpler.

Update 1

I cannot get the unmodified System.JSON unit to re-compile and link. Which I think means that the issue raised in that other question is broader than just the Classes unit. I think you will find this a tricky hurdle to overcome and recommend the use of a detour.

Update 2

The problem that appears to have been introduced in XE6, seems to have been resolved by the release of XE7. The unmodified System.JSON unit will compile and link in XE7.

Messmate answered 25/6, 2014 at 15:9 Comment(3)
Hi David, I don't think I'm using any modified compiler options. The note about XE6 could well be relevant. I successfully implemented my fix in XE2, I'm just migrating the project to XE6 and this is the only problem I've come across.Hopi
Thanks David, went with using a detour in the end using the code from here chee-yang.blogspot.co.uk/2008/11/hack-into-delphi-class.html. Not used this technique before but definitely prefer it to making copies of VCL source files.Hopi
The code for detouring in this answer is simpler still: #8978677Messmate
D
0

What if Delphi XE6 original System.JSON.dcu wasn't compiled with Delphi XE6 but it was compiled with one of the previous versions of Delphi.

You claim that you managed to implement your fix in Delphi XE2 using same approach by changing source and then recompiling System.JSON. SO I suggest you first make a comparison between original System.JSON files that ship with both Delphi XE2 and Delphi XE6.

If they are the same then the changed System.JSON.dcu that you managed to recompile with Delphi XE2 might also work with Delphi XE6.

Durable answered 25/6, 2014 at 19:1 Comment(6)
If that was the case, then you'd have to build your XE6 projects with an old version of the compiler.Messmate
Only if you would be recompiling exisintg dcu's that come with DelphiDurable
No. If the supplied rtl/vcl/fmx dcus were compiled with an older compiler then you'd need to compile your program with the same compiler.Messmate
So you are saying Delphi doesen't support linking DCU's compiled with different compiler versions.Durable
That's correct. There was one release that did, D2006 I think. But otherwise dcus are versioned. You need to link dcu files that were compiled by the same version.Messmate
Hi, I think the JSON implementation has changed somewhat between XE2 and XE6. In XE2 the fix was made in Data.DBXJSON.pas, it's now required in System.JSON.pas, so it's difficult to compare.Hopi
A
0

I resolved a similar issue by :

  1. Deleting the .dcu files which are on different versions ( i.e. conflicting files).

  2. Re-build the project to create new .dcu files.

Avis answered 31/1, 2020 at 8:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.