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

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 :
Copied System.JSON.pas from the standard VCL source folder to my project source folder
Added System.JSON.pas to my project (using the newly copied file)
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?

There are two common reasons for this issue:
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.
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.

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.

I resolved a similar issue by :
Deleting the .dcu files which are on different versions ( i.e. conflicting files).
Re-build the project to create new .dcu files.

Related

How could I go about loading functions from NTDLL without linking against it or any other DLLs?

I've been experimenting with loading functions from the Windows system DLLs using only the loader functions exported by NTDLL. This works as expected. For the sake of curiosity and getting an even better understanding of the process structure in NT-based systems, I've started trying to load functions from NTDLL by doing the following steps:
Load the PEB of the process from gs:[60h]
Iterate over the modules loaded into the process according to the loader to find NTDLL's base address
Parse the PE headers of NTDLL
Try to parse the export table to find LdrLoadDll, LdrGetDllHandle, and LdrGetProcedureAddress
This fails at step 4. After stepping through it in a debugger (both VS2019 and WinDbg Preview), it seems as though the offsets I've tried yield an invalid structure that leads to an access violation when my code compares the current function name to one of the ones I'm searching for. My code is being compiled and run on a 64-bit copy of Windows 10 Pro build 21364. Note that I'm using my own header that contains definitions for the structures used for this (these definitions are from winnt.h and here) because the Windows headers don't really play nice with the rest of my code. The function trying to do this is here. For the record, this is part of an attempt to implement my own libc (again, for the sake of curiosity). The code that calls the functions is here. Any help with this is tremendously appreciated.
Nevermind, turns out I had outdated verbose definitions of the structures I was using. I found better (more up-to-date) definitions at https://vergiliusproject.com.

NativeScript, Code Sharing and different environments

Note: this is not a dupe of this or this other question. Read on: this question is specific to the Code-Sharing template.
I am doing some pretty basic experiments with NativeScript, Angular and the code sharing templates (see: #nativescript/schematics).
Now I am doing some exploration / poc work on how different "build configuration" are supported by the framework. To be clear, I am searching for a simple -and hopefully official- way to have the application use a different version of a specific file (let's call it configuration.ts) based on the current platform (web/ios/android) and environment (development/production/staging?).
Doing the first part is obviously trivial - after all that is the prime purpose of the code sharing schematics. So, different versions of the same file are identified by different extensions. This page explain things pretty simply.
What I don't get as easily is if the framework/template supports any similar convention-based rule that can be used to switch between debug/release (or even better development/staging/production) versions of a file. Think for example of a config.ts file that contains different parameters based on the environment.
I have done some research in the topic, but I was unable to find a conclusive answer:
the old and now retired documentation for the appbuilder platform mentions a (.debug. and .release.) naming convention for files. I don't think this work anymore.
other sources mention passing parameters during the call to tns build / tns run and then fetching them via webpack env variable... See here. This may work, but seems oddly convoluted
third option that gets mentioned is to use hooks to customize the build (or use a plugin that should do the same)
lastly, for some odd reason, the #nativescript/schematics seems to generate a default project that contains two files called environment.ts and environment.prod.ts. I suspect those only work for the web version of the project (read: ng serve) - I wasn't able to get the mobile compiler to recognize files that end with debug.ts, prod.ts or release.ts
While it may be possible that what I am trying to do isn't just supported (yet?), the general confusion an dissenting opinions on the matter make me think I may be missing something.. somewhere.
In case this IS somehow supported, I also wonder how it may integrate with the NativeScript Sidekick app that is often suggested as a tool to ease the build/run process of NativeScript applications (there is no way to specify additional parameters for the tns commands that the Sidekick automates, the only options available are switching between debug/release mode), but this is probably better to be left for another question.
Environment files are not yet supported, passing environment variables from build command could be the viable solution for now.
But of course, you may write your own schematics if you like immediate support for environment files.
I did not look into sharing environment files between web and mobile yet - I do like Manoj's suggestion regarding modifying the schematics, but I'll have to cross that bridge when I get there I guess. I might have an answer to your second question regarding Sidekick. The latest version does support "Webpack" build option which seems to pass the --bundle parameter to tns. The caveat is that this option seems to be more sensitive to typescript errors, even relatively benign ones, so you have to be careful and make sure to fix them all prior to building. In my case I had to lock the version of #types/jasmine in package.json to "2.8.6" in order to avoid some incompatibility between that and the version of typescript that Sidekick's cloud solution is using. Another hint is to check "Clean Build" after npm dependency changes are made. Good luck!

Minify ceylon-sdk and ceylon-language when compiling to javascript

For an in-browser application written in ceylon-js it would be desirable to reduce the size of the ceylon.language-1.2.0.js file to only that what is actually needed.
This question was answered already.
How to use ceylon js (also with google closure compiler)
But the given solution involves manually editing javascript code resulting from compilation. This is not desirable since a compiler should produce code that hasnĀ“t to be edited manually after compilation (abstraction).
And it is not clear to me if google closure compiler can cope with the ceylon flavour of it in a reliable way.
Is it instead a solution to copy ceylon.language source in ceylon into the project and import only those parts of ceylon.language into the project that are required by it? Then compile to javascript. And then leave away ceylon.language-1.2.0.js at all from the client / in-browser application.
Now my questions:
What parts are needed in the most simple browser application? I think of something like Array(String) and the like.
Has that solution a chance to work absolutely reliable?
Will there be a better solution coming from the authors of ceylon that make this attempt obsolete?
The compilation of the language module to JS is a tricky process, because of the native stuff involved and because there are a couple of declarations that have to be in a certain order for things to work.
Minification is still pending, we are going to do it but it's not the highest priority right now, and we have to determine the best way to solve this problem; one option that has been discussed is to have a version of the language module without any metamodel info, for example.

Can't get MVVMCross core project to reference System.Xml.Linq

I'm quite new to MVVMCross but I've been actively using it for two weeks, at work and in a school project, and I am really enjoying it! Unfortunately, I've been stuck on the school project for 2 days now : we're asked to do a mobile Jabber client. This is not a big deal since I started it using Matrix XMPP library, which does most of the job and is easy to use. I decided to restart my project using MVVMCross, in order to have cleaner separated code and add a Windows Phone project, but Matrix absolutely needs System.Xml.Linq, and I can't get the core PCL to compile :
The type 'System.Xml.Linq.XElement' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Xml.Linq, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
As shown in Stuart Lodge's tutorial videos, I'm using profile 104, the the faulting dll is really present in the folder, I can't add it manually to project's references since VS prevents me from doing it (gently explaining that it's automatically loaded since .Net portable subset is included in references), I've updated and repaired my VS install "just in case"... and have no more idea left.
So, here are the questions :
is it really possible to use System.Xml.Linq with MVVMCross? or did I miss the big title explaining that what I'm trying to do is stupid?
if yes (that'd be great!) did/does someone experience the same problem? Even more interesting : did someone find a solution?
Thanks in advance!
Additional info : Windows8(x64), VS2012 Ultimate, trial license (school project...) for Xamarin.Android
UPDATE : following Stuart's answer, I compiled and ran the BestSellers sample, which uses System.Xml.Linq... without any problem. As it comes with an explicit reference to System.Xml.Linq (see first link in answer), I tried :
to delete it (and a few others) : VS holds it's promises, and really includes needed references as long as .Net Portable Subset is referenced, so everything rolls smooth.
to manually add this reference via Notepad to my .csproj : it doesn't change anything.
One thing tickles me in Stuart's answer : "perhaps it is something to do with the way the matrix uses XML.linq". Since the Matrix type I'm trying to use is just a descendant of System.Xml.Linq.XElement, which is widely used in BookViewModel.cs from sample, what could possibly be wrong with that?
"Solution" : The problem seems to be due to Matrix requiring a special version of System.Xml.Linq, which is not the one included when profile 104 for building PCL. I used file linking method as a workaround to share the core, and that works, though this is less elegant, readable, and harder to maintain...
Yes it is possible to use at least some of System.Xml.Linq
For example, see the BestSellers sample
csproj file - https://github.com/slodge/MvvmCross-Tutorials/blob/master/Sample%20-%20BestSellers/BestSellers/BestSellers/BestSellers.csproj#L49
example XML linq use - https://github.com/slodge/MvvmCross-Tutorials/blob/master/Sample%20-%20BestSellers/BestSellers/BestSellers/ViewModels/BookViewModel.cs#L44
For the problem you are seeing, I'm really not sure what the error is - perhaps it is something to do with the way the matrix uses XML.linq? You might have more luck of you open up this question to other tags like portable-class-library, XML-linq and windows-phone.

What is the difference between binary and source compatibility conceptually ?

In the context of webkit in chromium source code ,it says it is source compatible but not binary compatible. Does it suggest that we build .dll file of webkit and build it with chrome binary ?
(This answer doesn't talk about the specific context of WebKit - it's not clear what exactly you mean by the various "it says" parts. I've tried to give a more general answer.)
Suppose we have a library called LibFoo, and you have built an application called SuperBar which uses LibFoo v1.
Now LibFoo v1.1 comes out.
If this is binary compatible, then you should be able to just drop in the new binary, and SuperBar will work using the new code without any other changes
If this is only source compatible then you need to rebuild SuperBar against v1.1 before you'll be able to use it
I would think of it from the point of view of Linking
Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed.
Linking a class or interface involves verifying and preparing that
class or interface, its direct superclass, its direct superinterfaces,
and its element type (if it is an array type), if necessary.
If introducing a new change breaks the linking, then it is not source (code) compatible (as well as binary compatible)
If introducing a new change does not break the linking, then it is at least binary compatible