.NET
  Home arrow .NET arrow Page 9 - The Delphi Language, Part 1
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
.NET

The Delphi Language, Part 1
By: Xavier Pacheco
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 16
    2004-07-07

    Table of Contents:
  • The Delphi Language, Part 1
  • Procedures and Functions
  • Constants, Operators
  • Delphi Language Types
  • Variant Types
  • Variants in Expressions
  • Arrays
  • Records and Sets
  • Pointers
  • Classes and Objects

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    The Delphi Language, Part 1 - Pointers


    (Page 9 of 10 )

    A pointer is a variable that contains a memory location. You already saw an example of a pointer in the PChar type earlier in this chapter. Delphi's generic pointer type is called, aptly, Pointer. A Pointer is sometimes called an untyped pointer because it contains only a memory address, and the compiler doesn't maintain any information on the data to which it points. That notion, however, goes against the grain of Delphi's type-safe nature, so pointers in your code will usually be typed pointers.

    Note - In .NET, the System.IntPtr type is used to represent an opaque, untyped pointer.

    Typed pointers are declared by using the ^ (or pointer) operator in the Type section of your program. Typed pointers help the compiler keep track of exactly what kind of type a particular pointer points to, thus enabling the compiler to keep track of what you're doing (and can do) with a pointer variable. Here are some typical declarations for pointers:

    Type
      PInt = ^Integer; // PInt is now a pointer to an Integer
      Foo = record     // A record type
        GobbledyGook: string;
        Snarf: Double;
      end;
      PFoo = ^Foo;     // PFoo is a pointer to a foo type
    var
      P: Pointer;      // Untyped pointer
      P2: PFoo;        // Instance of PFoo

    Note - C/C++ programmers will notice the similarity between Delphi's ^ operator and C's * operator. Delphi's Pointer type corresponds to the C/C++ void * type.


    Remember that a pointer variable only stores a memory address. Allocating space for whatever the pointer points to is your job as a programmer. Previous versions of Delphi had many functions that enabled a developer to allocate and deallocate memory; however, because direct memory allocation is so rare in .NET, it is typically accomplished only via the System.Runtime.InteropServices.Marshal class. The following code demonstrates how to use this class to create and free a block of memory, as a well as copy some array data in and out of the block.

    {$UNSAFECODE ON}

    type
      TArray = array[0..31] of Char;

    procedure ArrayCopy; unsafe;
    var
      A1: TArray;
      A2: array of char;
      P: IntPtr;
    begin
      A1 := 'safety first'; // fill character array
      SetLength(A2, High(TArray) + 1);
      P := Marshal.AllocHGlobal(High(TArray) + 1);
      try
        Marshal.Copy(A1, 0, P, High(TArray) + 1); // copy A1 to temp
        Marshal.Copy(P, A2, 0, High(TArray) + 1); // copy temp to A2
        MessageBox.Show(A2); // show changed array
      finally
        Marshal.FreeHGlobal(P);
      end;
    end;

    If you want to access the data that a particular pointer points to, follow the pointer variable name with the ^ operator. This method is known as dereferencing the pointer. The following code illustrates working with pointers:

    procedure PointerFun; unsafe;
    var
      I: Integer;
      PI: ^Integer;
    begin
      I := 42;
      PI := @I; // points to I
      PI^ := 24; // changes I
      MessageBox.Show(I.ToString);
    end;

    The Delphi compiler employs strict type checking on pointer types. For example, the variables a and b in the following example aren't type compatible:

    var
      a: ^Integer;
      b: ^Integer;

    By contrast, the variables a and b in the equivalent declaration in C are type compatible:

    int *a;
    int *b

    The Delphi language creates a unique type for each pointer-to-type declaration, so you must create a named type if you want to assign values from a to b, as shown here:

    type
      PtrInteger = ^Integer; // create named type
    var
      a: PtrInteger;
     
    b: PtrInteger; // now a and b are compatible


    Note - When a pointer doesn't point to anything (its value is zero), its value is said to be nil, and it is often called a nil or null pointer.


    Null-Terminated Strings

    Earlier, this chapter mentions that Delphi has three different null-terminated string types: PChar, PAnsiChar, and PWideChar. As their names imply, each of these represents a null-terminated string of each of Delphi's three character types. In .NET, PChar is an alias for PWideChar, whereas PChar is an alias for PAnsiChar in Win32. In this chapter, we refer to each of these string types generically as PChar. The PChar type in Delphi exists mainly for backward compatibility with previous versions. A PChar is defined as a pointer to a string followed by a null (zero) value. Because it is a raw, unmanaged, unsafe pointer, memory for PChar types isn't automatically allocated and managed by .NET.

    In the Win32 flavor of Delphi, PChars are assignment compatible with strings. However, in .NET, these types are no longer compatible, which makes their use far less common in the .NET world.

    Variant Records

    The Delphi language also supports variant records, which enable different pieces of data to overlay the same portion of memory in the record. Not to be confused with the Variant data type, variant records enable each overlapping data field to be accessed independently. If your background is C, you'll recognize variant records as being the same concept as a union within a C struct. The following code shows a variant record in which a Double, Integer, and Char all occupy the same memory space:

    type
      TVariantRecord = record
        NullStrField: PChar;
        IntField: Integer;
        case Integer of
          0: (D: Double); 
          1: (I: Integer);
          2: (C: Char);
    end;

    Note - The rules of the Delphi language state that the variant portion of a record cannot be of any lifetime-managed type. This includes classes, interfaces, variants, dynamic arrays, and strings.


    Here's the C equivalent of the preceding type declaration:

    struct TUnionStruct
    {
      char * StrField;
      int IntField;
      union u
      {
        double D;
        int i;
        char c;
      };
    };

    Because variant records deal with explicit memory layout, they also are considered unsafe types.


    Note - Record memory layout can be controlled by the developer in .NET using the StructLayout and FieldOffset attributes.


    This chapter is from Delphi for .NET Developer's Guide, by Xavier Pacheco (Sams, 2004, ISBN: 0-672-32443-1). Check it out at your favorite bookstore today.

    Buy this book now.

    More .NET Articles
    More By Xavier Pacheco


     

    .NET ARTICLES

    - Using CrystalReportViewer to Display Crystal...
    - Creating Summary .Net Crystal Reports
    - More on Commands, Input and the WPF
    - Grouping and Aggregating When Querying LINQ ...
    - Commands, Input and the WPF
    - Keyboard and Ink Input with WPF
    - Mouse Input and the WPF
    - Input with Windows Presentation Foundation
    - Introducing LINQ with XML and Databases
    - An Introduction to LINQ
    - Querying LINQ to SQL: Basics
    - Completing a Simple Storefront with LINQ
    - Knowing Your Environment: the System.Environ...
    - Creating the Home Page for a Simple Storefro...
    - LINQ Quickly with Language Integrated Queries

     
    Best Practices for Windows Vista Migration Presentation
    Dell and Microsoft recently held a series of face-to-face seminars entitled, &qu....

     
    Creating a Culture for Code Reuse
    If you oversee development teams you know that like it or not proprietary and ex....

     
    Keys to Web Application Acceleration: Advances in Delivery Systems
    Accelerate Web apps by up to 5x. Ensure significantly faster access to the Web a....

     
    Optimizing Application Monitoring
    Tired of finding out from your customers that you're offline? This white paper e....

     
    Solaris to Solaris Migration -- Migrating applications from Sun SPARC to Dell PowerEdge R900
    This comprehensive Migration Guide reviews the approach that Principled Technolo....

     




    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway
    Stay green...Green IT