portable interface emulation

Top  Previous  Next

What is translated > Types > Records, Classes, Interfaces > Interfaces > Non-generic interfaces > portable interface emulation

Delphi’s interface model is tightly bound to the Component Object Model (COM), but its use in application logic (e.g., IFoo, Supports, as, TInterfacedObject) goes far beyond COM interop. To reproduce this model outside of the Windows ecosystem, Delphi2Cpp provides a fully portable interface system that:

 

Avoids <unknwn.h> and windows.h
Uses no platform-specific UUID or GUID registration APIs
Works on Linux, macOS, and embedded systems
preserves full semantics of as_di<T>, Supports, IInterface, and TInterfacedObject using RAII-based DelphiInterface<T> smart pointers

 

Although macros ensure that the generated code for portable platforms looks identical to the Windows version, the handling of GUIDs differs fundamentally.

 

In portable C++, GUIDs associated with interface structs are defined and registered automatically at static initialization time via the DEFINE_UUIDOF macro:

 

For example

 

#ifdef IS_PORTABLE

  DEFINE_UUIDOF(IMyInterface, "{01234567-89AB-CDEF-0123-456789ABCDEF}")

  DEFINE_UUIDOF(ISecondInterface, "{87654321-4321-4321-4321-BA0987654321}")

#endif

 

 

The underlying behavior of the macros—i.e., whether the GUID is actually registered at runtime or not—is determined by the presence of the IS_PORTABLE macro, which is set in the configuration header (d2c_config.h).

 

When IS_PORTABLE is defined, a global registry class TGuidRegistry is used. This class provides a thread-safe, bidirectional mapping between C++ type names (as strings) and their associated TGUID values. TGuidRegistry is implemented as a singleton and ensures that interface type information remains accessible at runtime, even in fully platform-independent builds.

 

Since __uuidof(T) is not available in portable C++, Delphi2Cpp defines:

 

template <typename T>

const TGUID& __d2c_uuidof(); // undefined unless specialized via DEFINE_UUIDOF

 

Complete example:

 

struct D2C_UUID("{01234567-89AB-CDEF-0123-456789ABCDEF}")

IMyInterface : public System::IInterface

{

    virtual void SayHello() = 0;

};

 

#ifdef IS_PORTABLE

  DEFINE_UUIDOF(IMyInterface, "{01234567-89AB-CDEF-0123-456789ABCDEF}")

#endif

 

// Usage:

DelphiInterface<IMyInterface> intf = as_di<IMyInterface>(new TMyObject());

//if (intf)

    intf->SayHello(); // reference count automatically managed

 

 

 

 

 

 

 



This page belongs to the Delphi2Cpp Documentation

Delphi2Cpp home  Content