The __declspec Keyword Extension

From RAD Studio
Jump to: navigation, search

Go Up to Support for Delphi Data Types and Language Concepts


Some arguments to the __declspec keyword extension provide language support for the libraries. These arguments are listed below. Macros for the declspec arguments and combinations of them are defined in sysmac.h. In most cases you do not need to specify these. When you do need to add them, you should use the macros.

__declspec(delphiclass)

The delphiclass argument is used for declarations of classes derived from TObject. These classes are created with the following compatibility:

  • Delphi-compatible RTTI
  • Library-compatible constructor/destructor behavior
  • Library-compatible exception handling

A library-compatible class has the following restrictions:

  • No virtual base classes are allowed.
  • No multiple inheritance is allowed except for the case described in Inheritance and Interfaces.
  • Must be dynamically allocated by using the global new operator.

    Note: In case an instance is statically allocated (for example, as a local variable), the compiler simply ignores the declspec directive, with no warning.

  • Must have a destructor.
  • Copy constructors and assignment operators are not compiler-generated for library-derived classes.
  • A class declaration that is translated from Delphi needs this modifier if the compiler needs to know that the class is derived from TObject.

__declspec(delphirecord)

The delphirecord storage class attribute is used when converting Delphi records into C++ classes/structs in .hpp headers (using the Delphi compiler  dcc32 -JPHNE <filename.pas>). In Delphi there is a convention regarding records being returned from functions, which states that a function returning a record returns a hidden parameter pointing to the record to be returned. Delphi returns a pointer to a location that is zero initialized, whereas C++ does not offer such a guarantee. For compliance, when C++ finds a struct that is being returned from a function and is flagged as __declspec(delphirecord), it zeroes out the memory location.

__declspec(delphireturn)

The delphireturn argument is for internal use only by the libraries in C++Builder. It is used for declarations of classes that were created in C++Builder to support Delphi built-in data types and language constructs, because they do not have a native C++ type. These include Currency, UnicodeString, AnsiString, Variant, TDateTime, and Set. The delphireturn argument marks C++ classes for library-compatible handling in function calls as parameters and return values. This modifier is needed when passing a structure by value to a function between Delphi and C++.

__declspec(delphirtti)

The delphirtti argument causes the compiler to include runtime type information in a class when it is compiled. When this modifier is used, the compiler generates runtime type information for all fields, methods, and properties that are declared in a published section. For interfaces, the compiler generates runtime type information for all methods of the interface. If a class is compiled with runtime type information, all of its descendants also include runtime type information. Because the TPersistent class is compiled with runtime type information, this means that there is no need to use this modifier with any classes you create that have TPersistent as an ancestor. This modifier is primarily used for interfaces in applications that implement or use Web Services.

__declspec(dynamic)

The dynamic argument is used for declarations of dynamic functions. Dynamic functions are similar to virtual functions except that they are stored only in the vtables for the objects that define them, not in descendent vtables. If you call a dynamic function, and that function is not defined in your object, the vtables of its ancestors are searched until the function is found. Dynamic functions are only valid for classes derived from TObject.

__declspec(hidesbase)

The hidesbase argument preserves Delphi program semantics when porting Delphi virtual and override functions to C++Builder. In Delphi, virtual functions in base classes can appear in the derived class as a function of the same name, but which is intended to be a completely new function with no explicit relation to the earlier one.

The compilers use the HIDESBASE macro, defined in sysmac.h, to specify that these types of function declarations are completely separate. For example, if a base class, T1, declares a virtual function, func, taking no arguments, and its derived class, T2, declared a function with the same name and signature, the Delphi compiler DCC32 - jphn would produce an HPP file with the following prototype:

    virtual void T1::func(void) ;
    HIDESBASE void T2::func(void) ;

Without the HIDESBASE declaration, the C++ program semantics indicate that virtual function T1::func() is being overridden by T2::func().

__declspec(package)

The package argument indicates that the code defining the class can be compiled in a package. This modifier is auto-generated by the compiler when creating packages in the IDE.

__declspec(pascalimplementation)

The pascalimplementation argument indicates that the code defining the class was implemented in Delphi. This modifier appears in an Delphi portability header file with an .hpp extension.

__declspec(uuid)

The uuid argument associates a class with a globally unique identifier (GUID). This can be used with any class, but is typically used with classes that represent Delphi interfaces (or COM interfaces). You can retrieve the GUID of a class that was declared using this modifier by calling the __uuidof directive.

See Also