Delphi for .Net 编译器预览 - by John Kaster
|Welcome zhang jinyu|
|AppServer||C++||CORBA||Delphi & Kylix||InterBase||Java||Linux||TeamSource DSP|
Abstract:A first look at the Delphi for .NET compiler features and Delphi's new language syntax
by John Kaster and Danny Thorpe
At BorCon 2002, Borland started providing more technical details on our support under development for the .NET platform. This article introduces some of the planned enhancements to the Delphi language and introduces the prototype "Delphi for .NET" compiler. Unless otherwise indicated, the language features discussed here will first be seen in the Delphi for .NET compiler. Furthermore, all of the features discussed in this article may not be introduced in the preview release. When possible, features already implemented in the compiler will be listed, but since the compiler is in beta right now, not much emphasis will be placed on distinguishing what's currently implemented and what's not.
For a good, brief overview of .NET and an introduction to some of the terms mentioned in this article, see http://arstechnica.com/paedia/n/net/net-1.html.
The Delphi for .NET compiler produces Common Intermediate Language (CIL) applications. These applications can run anywhere the .NET run-time is available as fully managed applications. This means that Delphi applications can now move beyond their traditional Windows/Intel platform to any other platform that has a .NET runtime, such as the .NET compact framework available for tablet PCs, phones, and PDAs.
The Delphi command line compiler for IL is
In an effort to maintain the trend of asking about pronunciations ("Is it 'delf-ee' or 'delf-eye'?"), I feel obligated to mention that the R&D team pronounces the compiler as "diesel."
A Delphi for .NET GUI application
As with Kylix, a basic step in our .NET support was getting a compiler that actually produces the appropriate "machine code" executable. In this case, that machine is .NET. A form designer is not currently available for Delphi for .NET, so you will notice that the following code actually initializes the menu items, button, listbox, and up/down control.
Note! The unit
The source code listed above is contained in
After compiling the application, of course we should run it. Here's what the application looks like after a little resizing to minimize the image size.
Fully Managed Code
This application is a 100% managed code application, as the results of PEVerify show:
You can use Microsoft IL Disassembler (ildasm) to examine the executable.
You can examine the .NET assembler code for any module.
Delphi for .NET code also works with Lutz Roeder's excellent utility, Reflector. (This link contains some other great .NET utilities as well.)
The .NET compiler
The Delphi for .NET compiler is more than just a port of the existing Delphi compiler. There is a new code generator, a new linker, significant new syntax, and a new runtime library. Of course, it is also very important to maintain language compatibility, so you will see some familiar old friends in Delphi for .NET as well:
In order to fully embrace the CLR and make Delphi a first class citizen in the new world of managed code, some language features must be deprecated, and others are the subject of ongoing research. Though many of these details are still being researched and implemented, it is hoped that the following information will be useful for understanding the new language features of Delphi for .NET.
Unsafe code warnings in Delphi
Starting with Delphi 7, the compiler includes three new warnings that can help you locate code that is non-portable (i.e. it uses a deprecated language feature or type), or unsafe in the .NET Framework. In the .NET Framework, "unsafe" simply means that the code cannot be verified by the static analysis performed by the CLR when the code is loaded. The compiler can warn about the usage of unsafe types, unsafe code, and unsafe casts.
Unsafe typesPChar, PWideChar, and PAnsiChar Untyped pointers Untyped var and out parameters File of <type> Real48 Variant records (records containing overlapping fields)
Unsafe codeAbsolute variables Addr(), Ptr(), Hi(), Lo(), Swap() standard procedures BlockRead(), and BlockWrite() Fail() GetMem(), FreeMem(), ReallocMem() inline assembler the @ operator
Unsafe castsCasting an object instance to a type that is not an ancestor or descendent of the instance type Casting a record type to anything else
These new warnings are disabled by default. They can be enabled with the IDE Project Options dialog box, or with the compiler directive:
They can also be enabled with the -W command line switch:
Note there is no space before or after the '+' character on the command line switch.
Note: These new warnings are in the Delphi 7 (and beyond) compiler for Win32 (dcc32). They are not in the Delphi for .NET Preview compiler (dccil).
Deprecated Language Features
The dccil compiler will also deprecate some existing language features, listed in the following table.
CLR and Delphi
The new Delphi compiler will provide access to the .NET CLR (Common Language Run-time). Delphi developers will be instantly familiar with the CLR not just because it resembles the VCL so closely, but also because compatibility type mappings will be provided.
The following table shows some classes and technology areas that map easily between Delphi and the .NET runtime.
Assemblies and Delphi
The Delphi for .NET compiler treats CLR assemblies like Delphi packages. The compiler supports direct symbol importing from metadata. Header file translations are no longer needed. Symbols can be imported from any Common Language Specification (CLS) compliant .NET assembly, produced by any .NET language tool. Conceptually, every .NET assembly contains the equivalent of a DCP (which is a collection of DCUs) and a BPL, all lumped into one file.
The compiler supports the
The Delphi package syntax produces assemblies. Furthermore, the package syntax will still provide the option of linking referred code directly into your exe, or making it an external reference.
The .NET assemblies don't give you the option of internal or external linking of code. You can support internal or external linking by distributing the DCUs as well as DCPs + BPLs. You cannot link code compiled in a package into an exe. You have to have a DCU (or source) to do that. The DCCIL compiler behaves the same as the DCC32 compiler.
You should also know that Delphi for .NET will preserve the case for the namespaces you create. C#'s recognition of namespaces is case sensitive, so if you use a Delphi for .NET assembly with C#, you will need to match the original case of the namespace you created. Delphi's recognition of namespaces is not case sensitive, so if you don't keep this behavioral difference of the languages in mind, you might run into problems later.
Delphi Language Enhancements
I'm sure you were all looking closely at the code above, even though I told you it would change. Some of the enhancements to Delphi are obvious by looking at the source code, but not all of them are demonstrated in the above code sample.
Let's look at a partial list of Delphi language enhancements.
By examining the above source code, one obvious change should be the support for unit namespaces. Namespaces allow you to access units with fully qualified identifiers, such as:
The Delphi unit defines its own namespace with dotted names in the unit identifiers and file names. (The file name and unit name still match, with the ".pas" omitted from the unit name.)
You can configure project-specific namespace resolution. Project namespaces are a great way to eliminate
Project namespace search path
There will also be support for a project namespace search path, which supports searching the namespace path for unqualified unit names on the search path. Consider this hypothetical example:
This reference would resolve to
Default project namespace
You can also create units that can be compiled into multiple project namespaces. For example,
would compile to
Reserved words or keywords are allowed after the first identifier. For example, in the following code:
Qualified identifiers can appear in type expressions, but not in identifier declarations.
The Common Language Specification includes this extended identifier syntax. The dccil compiler will provide access to all CLS compliant symbols in CLR assemblies.
Consider the following code:
In the above example,
Delphi for .NET will support standard attributes, such as
Declaring custom attributes
Delphi allows you to create custom attributes you can use for any of your .NET application source code, such as the
A poster child for custom attributes might be the
Class (static) data
You can have class variables in your objects. This allows you to do things like perform instance counts or track information that is class specific rather than instance specific in your objects.
Class properties work like class fields. The getters and setters must be class methods or class fields.
Class static methods
Class static methods work the same as traditional Delphi class methods, except that there is no "self" parameter available in the method body. This is a CLR requirement because some languages do not support the hybrid behaviors Delphi has, where you can have routines that are not part of an object. Traditional Delphi class methods (which do have a "Self" in the body of the method) will also be supported.
Types can be "boxed" into object wrappers. These value types are not reference types. They are the actual instance of the type. Value semantics are supported for assignment and copying data. Record types are an example of value types in Delphi. Records can inherit from other records, and records can contain non-virtual methods, properties, and nested types.
When value types are boxed, a fresh copy of the value is made and a distinct object reference is returned. This distinct object reference is a reference to data that is completely independent of the underlying value type. For the following code,
Boxing of value types in Delphi for .NET is a requirement. Boxing support is not planned for Win32 or Linux Delphi language implementations.
Records with inheritance
Delphi records will be implemented as value types in CLR. Record inheritance is an aspect of value types. Records with non-virtual methods is another aspect of value type support.
Records with methods
The declaration of methods on
A sealed class cannot be inherited from. Value types can only inherit from abstract value type classes, and only sealed value type classes can be instantiated. Value types are highly deterministic, and decidedly non-polymorphic.
The final directive on a virtual method (or override) indicates that this method cannot be overridden in descendent classes. Descendents may still introduce new virtual methods with the same name as the inherited method, but since they do not override the inherited method (occupy the same vmt slot as the inherited method), they do not participate in polymorphic calls to the inherited method.
With multicast events, you can have multiple listeners for each event. This event model is different from the Win32 event model, where an event is consumed and discarded by the first component responding to it. With event listeners, multiple components can respond to the same message (for example, all controls could respond to a "repaint" event).
In this event listener model, you can only remove your own listener.
Support for multicast events in Delphi for .NET is a requirement. Support for multicast events may appear in future releases of Delphi for Win32 and Linux.
Interface method resolution
Interface method resolution provides a convenient shorthand for implementing methods referenced in an interface. By default, the compiler attempts to bind a method name to a method of the same name in the class implementing the interface. With the following code,
The new version would be:
A reference to
When multiple interfaces are used, interface method resolution becomes even more valuable. The following code illustrates:
Array property overloads
Array property overloads will also be supported. The following example shows the probable syntax for overloading array property references.
Overload of array properties is required for CLS compliance. For example, the CLR
This document is intended to introduce some of the new features and concepts under research for the Delphi for .NET compiler. While every attempt has been made to keep this information accurate, all of it is subject to change. Compiler support for .NET has provided some exciting opportunities for enhancement to the Delphi language. The language enhancements discussed here are for the Delphi for .NET compiler unless otherwise stated. Hopefully, you like what you see so far.
Stay tuned to this web site, as more articles on Delphi for .NET are coming very soon.
Article ID: 28972 Publish Date: August 06, 2002 Last Modified: August 05, 2002