Tech Report on going from Delphi Win32 to NextGet Mobile compilers

Hi,

After porting our codebase to the mobile compilers, these observations which
in part are contradicting statements in Delphi docs, might help others on
the same path (applies to XE7):

1.) ZeroBased strings. First best thing you can do:

{$IFDEF NEXTGEN}
   {$ZEROBASEDSTRINGS OFF}
{$ENDIF}

And have that in your old or new pascal sources. This makes the old code
100% portable and new code compatible with old code and new code compatible
with itself. All RTL strings functions in Delphi Win32 and Mobile compilers
are namely 1-based, except for a few methods invoked on the string itself as
methods. (which you should use with awareness that they are zero based or
avoid their use completely).

2.) The use of [Weak] and associated possibility for performance issues:

Replace all [Weak] with [Unsafe]. You can also make function result unsafe
like this:

function aFun: TMyObject unsafe;
begin
        Result := MyCopy; //does not increase FRefCount
end;

[Unsafe] has the following meaning:
Treat the variable without Automatic reference counting. This is the same
behavior that Delphi Win32 applies to all object pointers. If you managed to
survive Delphi Win32, few pointers which are not ARC will not hurt here
either.

You can write the following without any problems:

var a,c: TObj;
    [Unsafe]
    b: TObj;
begin
    a := TObj.Create;  //FRefCount = 1
    b := a;//FRefCount = 1 // does not increase
    c := b; //FRefCount = 2
    a.Free; //FRefCount = 1
end;

Note that you can assign unsafe variable to arc counted var as well. This is
all perfectly fine as long as you don’t make use of b, after a and c are
nilled.

3.) Function parameters which are object type:

Specify all object parameters to be "const":

procedure aFun(a: TMyObject);
begin
end;

should become:

procedure aFun(const a: TMyObject);
begin
end;

If you do this consistently within your own code, there will be no
performance issues due to automatic reference counting (ARC), because
FRefCount does not change when the parameter is passed as "const". Const in
this case has the same effect as if the parameter would be marked as
[Unsafe].

If you combine const (for params) with unsafe (for functions and
fields/vars) you can work around all and any performance issues imposed due
to ARC and reduce the number of __ObjAddRef and __ObjRelease calls to the
same count as present in Delphi Win32 compiler.

4.) All this (points 1 to 3) can only fix issues in your own code, but of
course Delphi FireMonkey and RTL will continue to have issues, where
parameters are not declared as const and [Weak] is used instead of [Unsafe]
unnecessarily.

[Weak] should only be employed, if you cant tell immediately due to
threading or some complex object code, when the object pointer is going to
be nilled. To use [Weak] in any great count is of course pointless and
unnecessarily drains computing resources. The most typical case where [Weak]
can be replaced with [Unsafe] without worries:

TParent = class
    Child: TChild;
end;

TChild = class
private
    [Weak]  //  <-- Replace with [Unsafe] to avoid performance issues
    fParent: TParent;
public
   constructor Create(Owner: TParent); override;
end;

constructor TChild.Create(Owner: TParent);
begin
     inherited;
     fParent := Owner;
end;

This is because in this structure you have a warranty that Child will always
be destroyed before Parent.

5.) DisposeOf is required for all TForm objects. Calling DisposeOf does not
trigger forms OnClose event. I am not sure of this is a bug or what and I
still have to check if aForm.Close triggers DisposeOf.   Anyhow, all TForm
objects need to be cleared manually, it is not sufficient to write:

var a: TForm2;
      [Unsafe]
      b: TForm2;
begin
    a := TForm2.Create(Self);
    b := a;
    a := nil; // this does not free the TForm object on NextGen compiler,
because variable "a" has reference count greater than 1 (it is 3 after "a"
is nilled)
//This is how you verify:
    ShowMessage('FRefCount  = ' + IntToStr(b.FRefCount);


6.) Local variable is set to nil, before the destructor are called:

a := TMyObject.Create;
a.MyEvent := AEvent;
a.Free;

If AEvent references "a" and AEvent is called from the destructor for
TMyObject this "a" will be nil before destructor for a is called. This is of
course not the case in Delphi Win32.


Kind Regards!
Atmapuri
0
Janez
3/27/2015 9:39:38 AM
embarcadero.delphi.non-tech 5933 articles. 1 followers. Follow

3 Replies
733 Views

Similar Articles

[PageSpeed] 14

Janez wrote:

> 1.) ZeroBased strings. First best thing you can do:
> 
> {$IFDEF NEXTGEN}
> {$ZEROBASEDSTRINGS OFF}
> {$ENDIF}
>
> And have that in your old or new pascal sources. This makes the old
> code 100% portable and new code compatible with old code and new
> code compatible with itself. All RTL strings functions in Delphi Win32
> and Mobile compilers are namely 1-based, except for a few methods
> invoked on the string itself as methods. (which you should use with
> awareness that they are zero based or avoid their use completely).

The only thing that ZBS affects is the '[]' operator, nothing else.  Since 
string helper methods are all zero-based on both mobile and desktop, and 
RTL functions are all 1-based on both mobile and desktop, your code will 
be 100% portable without having to resort to {$ZEROBASEDSTRINGS OFF} if you 
can avoid using the '[]' operator .

> Replace all [Weak] with [Unsafe].

That is debatable.  [Weak] and [Unsafe] are semantically different, so [Unsafe] 
may not always be the best choice.

> You can also make function result unsafe like this:
> 
> function aFun: TMyObject unsafe;

The correct way to make the Result unsafe is to do it the way the documentation 
says:

{code}
[Result: unsafe] function aFun: TMyObject;
{code}

There is a difference between marking just the Result as unsafe versus marking 
the entire function as unsafe.

> Specify all object parameters to be "const":

Or [Unsafe], if 'const' is not appropriate for the function:

{code}
procedure aFun([Unsafe] a: TMyObject);
begin
end;
{code}

> 5.) DisposeOf is required for all TForm objects.

The only reason your example requires that is because you assigned an Owner, 
which maintains strong references to the Form, as does the global TScreen 
object.

> Calling DisposeOf does not trigger forms OnClose event. I am not sure
> of this is a bug or what

Not a bug.  Calling Free() on a TForm in a desktop platform does not trigger 
OnClose, either.  Never has.

> I still have to check if aForm.Close triggers DisposeOf.

It does not.  Just like in VCL, the OnClose event in FMX has an Action output 
parameter, and if set to caFree it triggers a delayed Free(), not DisposeOf().

> a := nil; // this does not free the TForm object on NextGen compiler,
> because variable "a" has reference count greater than 1 (it is 3 after
> "a" is nilled)

You can use Self.RemoveComponent(a) to clear most of those references, but 
not all of them.

> //This is how you verify:
> ShowMessage('FRefCount  = ' + IntToStr(b.FRefCount);

TObject.FRefCount is protected.  You have to use the public RefCount property 
instead:

{code}
ShowMessage('RefCount  = ' + IntToStr(b.RefCount);
{code}

> 6.) Local variable is set to nil, before the destructor are called:
> 
> a := TMyObject.Create;
> a.MyEvent := AEvent;
> a.Free;

> If AEvent references "a"

Strong or weak?

> and AEvent is called from the destructor for TMyObject this
> "a" will be nil before destructor for a is called.

So?  "a" is jst a local variable, AEvent has its own reference to TMyObject, 
and the destructor has its Self parameter as well.  The object is still in 
memory while its destructor is running.  So what is the actual problem if 
the local "a" variable is nil'ed? Nobody should be using it during destruction.

-- 
Remy Lebeau (TeamB)
0
Remy
3/27/2015 1:01:01 AM
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> The correct way to make the Result unsafe is to do it the way the documentation 
> says:
> 
> {code}
> [Result: unsafe] function aFun: TMyObject;
> {code}
> 
> There is a difference between marking just the Result as unsafe versus marking 
> the entire function as unsafe.
> 
> > Specify all object parameters to be "const":
> 
> Or [Unsafe], if 'const' is not appropriate for the function:
> 
> {code}
> procedure aFun([Unsafe] a: TMyObject);
> begin
> end;
> {code}

When code becomes as ugly as this, and the programmer has to start worrying about things he/she never had to worry about before (and they make a big difference, especially performance-wise), then you have to start questioning the efficacy of the compiler changes that were made. Perhaps a step in the wrong direction has been made here. I am still happy with BCB5!
--
Mark Jacobs
www.critical.co.uk
0
Mark
3/30/2015 10:47:04 AM
> ... then you have to start questioning the efficacy of the compiler 
> changes that were made.
> Perhaps a step in the wrong direction has been made here.

+1.
There are a lot of other and more important tasks with the and new 
framework, CPU and OS platforms.
I cant remember a discussion about "we want ARC".

Ronald
0
Ronald
3/30/2015 12:59:33 PM
Reply:

Similar Artilces:

ANN: Delphi HTML Reports preview
Very simple to use - buid complex reports in 10 minutes. All you need to know - SQL, HTML, CSS. Use all power of HTML4 and CSS3 in any part of report. Features: Barcodes Multiline headers Groups Cross-tabs (any level) Transformations (cross-tab with range) Pictures (+from database) Master/Detail (any level) Supports all databases and db-libraries (writing adapter for any db-acess library takes only 5 minutes) Standalone reports - no need for delphi forms/datasets. 100% native Delhi code. All Delphi versions - from Delphi 6 to XE6 (VCL). 32/64 bit. Supports Unicode for...

Delphi XE5
Hi :-) Installed Delphi XE5 (RAD Studio Enterprise) and used it for a while. Then I changed the installation and added the mobile parts to do mobile Application Development. Installation gave no errors and I can start the Android emulator and I see my mobile phone Connects fine and becomes an available target. When starting a New blank (or any other) mobile Project I can not compile. Get the same error every time. Even when doing nothing at all before compiling. [DCC Fatal Error] Project1.dpr(1): F1027 Unit not found: 'System.pas' or binary equivalents (.dcu/.o) Cannot ...

Migrate from Delphi 2007 for Win32 to Delphi XE
we use Delphi 2007 for Win32 to support legacy (32Bit) OWL-based pascal applications (yes i know it was a mistake not to switch to VCL 15 years ago). could our applications still be opened and compiled with Delphi XE? The existing projects are all plain Pascal-Code, coming back from the times of Turbo Pascal for Windows and later on Borland Pascal. Are there any improvements we could profit from (i.e IDE, Debugger)? Thanks Andrej > {quote:title=Andrej Dimic wrote:}{quote} > could our applications still be opened and compiled with Delphi XE? I'm not sure, but I guess ...

Delphi.NET loading Delphi.Win32 Driver
Hi, What I'm trying to do is marshal an array of cardinal (or integer) back into managed memory from a win32 dll. I know how to pass managed memory into a win32 dll {code} var aa : array of Integer; Buffer : IntPtr; begin SetLength(aa,2); aa[0] := 1; aa[1] := 80; if not Supports(ExtractFilePath(Application.ExeName)+'Win32_Library\SDK_Driver.Win32.io', TypeOf(IMyFunctions), MyFunctions) then Exit; //loads the driver into memory. MyFunctions contains the method names found in the SDK_Driver. Buffer := Marshal.AllocHGlobal(2 * {Marshal.SystemDefaultC...

here's a tech question for non-tech
I have not had occasion to want to do this before, so I'm hoping someone can enlighten me. I have an app built in D7, and it's rather complex in its functionality. Is it possible to rebuild the app to run as a service? Would that require separating the user interface from the app? Thanks, Bill William Meyer wrote on 4/22/2010 : > I have not had occasion to want to do this before, so I'm hoping > someone can enlighten me. I have an app built in D7, and it's rather > complex in its functionality. Is it possible to rebuild the app to run > as a service?...

delphi Win32 using delphi .NET dll
Hi, I'm trying to use a delphi.NET dll in delphi.WIN32. I am currently using CodeGear Delphi 2007 with version2(base version) of .NET I can get the dll to import into the WIN32 application the only problem is when i include things such as: "using Classes,DateUtils, SysUtils" in the .NET dll the win32 application will instantly hang when any of the dll functions are called. Any help would be great thanks. Also I have tried this example and it also crashes for me? http://cc.embarcadero.com/Item/22688 -Braden I also found this.. "The problem is that, wehn you instal...

Converting Delphi for Win32 to Delphi .Net(Prism)
Hi, I am currently migrating a project from Delphi for Win32 to Delphi.net. Part of my code currently goes into a directory and pulls out a random file from this directory and loads the contents of the file for me. This code doesn't seem to work in Delphi.Net. It uses PString and a number of functions in SysUtils that don't seem to be present in Delphi.net's SysUtils file. If anyone can help me please, it would be greatly appreciated! Many thanks, Jonathan Mackey Jonathan Mackey a écrit : > I am currently migrating a project from Delphi for Win32 to &...

Win32 program: Delphi 7 vs Delphi XE5
How is a D7 Win32 program compared to a Delphi XE5 one in terms of stability and performance? Is Delphi XE5 good enough for a big ERP project with several DLL's and hundreds of units and forms? Thanks in advance Am 26.12.2013 15:02, schrieb lior ilan: > How is a D7 Win32 program compared to a Delphi XE5 one in terms of stability > and performance? > Is Delphi XE5 good enough for a big ERP project with several DLL's and > hundreds of units and forms? > Thanks in advance > Hello, XE5 has increased functionality. Stability seems to be ok for most ...

Delphi and Delphi for .Net
It seems that Delphi for .Net is slower than Delphi Win32 native applicaiton. I would like to know is it true all .Net application is slower than Win32 native applicaiton or it is Delphi for .Net only. Your information is great appreciated, Inung On 2011-06-21 18:20:17 +0100, Inung Huang said: > It seems that Delphi for .Net is slower than Delphi Win32 native applicaiton. > I would like to know is it true all .Net application is slower than > Win32 native applicaiton or it is Delphi for .Net only. If you are only running the code in the application once then, yes, yo...

Debugging DLL compiled with Delphi 7 in Delphi XE5
Dear Sirs/Madams, We are considering changing from Delphi 7 to Delphi XE5. Our project consists of a dll and an .exe file. I have begun converting the .exe file to Delphi XE5 and have successfully accessed the DLL compiled with Delphi 7. When I debug the DLL (using the "run parameters" and changing "host application" to the .exe file) in Delphi 7 I can set breakpoints etc. and they are triggered. However, when I attempt to debug the project in XE5, I get the following message: Module Load: xxx.dll. No Debug Info. Base Address: $015A0000. Process xxx.exe (2928) ...

Win32 Delphi language features introduced since Delphi 7
Hi, Am I right in thinking that the language features introduced since Delphi 7 fall into the categories: a) language features dictated by .Net compatibility. e.g. Namespaces, Inlining, records with methods, operator overloading, pure interfaces, generics, extended RTTI and reflection; b) Unicode strings and supporting procedures? c) 64-bit support What other language features, if any, have been introduced since D7? Had most of the post-D7 languages features, except for generics, Unicode strings, and 64-bit support, been introduced in or before Delphi 2005? How bug-free were ...

Delphi 7 versus Delphi 2010 compiler directive {$Q-}
Hi, Could it be correct that there's a bug in Delphi7 where the compiler directive {$Q-} and {$Q+} works completely the opposite? When trying to build an existing Delhi 7 project in Delphi 2010 i found this weird behaviour. In D7 {$Q-} set overflow cheking on and in Delphi 2010 off ????? Regards, Arno Brinkman ABVisie -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Firebird open source database with many powerful SQL features: http://www.firebirdsql.org http://www.firebirdsql.info General database developer support: http://www.databasedevelopmentforum.com Support list for ...

dll fails when compiled with delphi 2010, but works with delphi 7
I may be doing good if someone can just point me to the right forum I have not created a dll for some time and have not written one with 2010 before. The dll I am creating will be called as a cfx function by either a ColdFusion or BlueDragon webserver. I have written cfx DLLs in the past. The function declaration is below, it is the standard declaration from ColdFusion or Bluegradon documention on creating a CFX. procedure ProcessTagRequest(Request: TCFXRequest); export; cdecl; Since this was the first time using 2010 I wrote a very basic function to build off that was not much mor...

Attempting to compile Delphi 5 code in Delphi XE5 is failing
Greetings All, If I'm not in the correct formum please tell me which one I should be in. Just upgraded to Delphi XE5 and am attempting to compile one of my Delphi 5 projects. I used Interbase Express I use either TDataSource -> TCDSProvider -> TDataSetProvider -> TIBQuery or TDataSource -> TClientDataSet -> TDataSetProvider -> TIBQuery Also used TIBDatabase, TIBTransaction, and TIBStoredProc I open the smallest project I have and click compile and almost immediately I receive this error Checking project dependencies... Compiling CITranEngine.dproj...

Web resources about - Tech Report on going from Delphi Win32 to NextGet Mobile compilers - embarcadero.delphi.non-tech

Compiler - Wikipedia, the free encyclopedia
... , or external linking . The most common reason for wanting to transform source code is to create an executable program. The name "compiler" ...

Compiler - Wikipedia, the free encyclopedia
"Compile" and "compiling" redirect here. For the software company, see Compile (publisher) . For other uses, see Compilation . This article has ...

Facebook Open-Sources HipHop PHP Compiler Software
Earlier this morning, Facebook officially made their new PHP “compiler,” called HipHop, available as open source software. In the blog post by ...

Art in the Age of Matter Compilers
jurvetson posted a photo: Sheba may be the harbinger of art in the digital age — a mathematical sculptor with digital matter. She manipulates ...

Interpreters and Compilers (Bits and Bytes, Episode 6) - YouTube
This animation explains the difference between interpreters and compilers. It is from Episode 6 of the classic 1983 television series, Bits and ...

Typesafe cofounder forking Scala compiler
The main contributor to the Scala compiler, Paul Phillips, has announced on GitHub that he is forking the compiler to “fix some of the innumerable ...

Does Apple's new developer agreement ban Adobe's Flash-to-iPhone compiler?
Given that any kind of formal truce between Apple and Adobe was essentially blown out of the water by Steve Job's very public slating of Flash ...

Apple seeds devs with Safari 5.2 for Lion, Xcode 4.4 with new LLVM compiler
... to the general public this summer. Among the new features: According to Apple, Xcode 4.4 includes an editor for Collada 3D files, compiler support ...

NVIDIA and Continuum Analytics Announce NumbaPro, A Python CUDA Compiler
... are announcing that they are bringing Python support to CUDA. Specifically, Continuum Analytics’ will be introducing a new Python CUDA compiler, ...

IntelliJ Releases IDEA 12, Brings Improved UI, New Compiler Mode, Android UI Designer, And More
I'm not going to pretend to be a developer here, and I'll openly admit that the bulk of what IDEA 12 does is over my head. However, I do understand ...

Resources last updated: 12/13/2015 8:06:20 AM