XDL is a definition language similar to Microsoft IDL but with versioning support and less strict rules.
xdl <input_file>.xdl <output_dir> [prefix]
input_file
: the name of the input xdl file
output_dir
: the folder where headers are generated into
prefix
: the prefix to use for the generated factory function and template macros, if no prefix is specified then none of that is generated
The factory function is defined like this
template<template<abi_t> typename T>
inline HRESULT PrefixCreateInstance(abi_t ABI, void **ppvObject)
So if prefix
was set to Example
, the factory will be named ExampleCreateInstance
.
It can be used like this:
abi_t abi;
abi.Major = 10;
abi.Minor = 0;
abi.Build = 15063;
abi.Revision = 0;
IVersionedClassFactory* pClass;
HRESULT hr = PrefixCreateInstance<VersionedClassFactory>(abi, (void**)&pClass);
The factory class can be defined like this:
[no_uuid]
interface IVersionedClassFactory
{
HRESULT CreateMyVersionedClass([out] void** ppClass);
};
[force_abi]
class VersionedClassFactory : IVersionedClassFactory
{
};
and the implementation of CreateMyVersionedClass
can look like this:
HRESULT CreateMyVersionedClass(void** ppClass)
{
*ppClass = new MyVersionedClass<ABI>();
}
- Support full C declarator syntax (including function pointers)
- Recognize annotations and translate them to SAL on the C++ types
- Support for defining constants
- Support for simple expressions with constants (i.e.
1 + 1
) - Proper error checking and better error messages
- Support for optionally generating headers for imports
- Support for multiple XDL file inputs
The following example showcases how to define a simple interface that makes use of basic XDL versioning features
import "unknown.xdl";
namespace simple_example
{
[uuid("f0d7fd9c-33a3-4fc3-abe1-511c8917dbf6")]
interface ISimpleClass : IUnknown
{
[removed(10,0,15063,0)]
UINT m_StringsCount;
[added(10,0,15063,0)]
UINT64 m_StringsCount;
[removed(10,0,15063,0)]
UINT AddString([in] LPCSTR pString);
[added(10,0,15063,0)]
UINT64 AddString([in] LPCWSTR lpString);
[removed(10,0,15063,0)]
UINT GetString([out] LPCSTR pString, [in] UINT size, [in] UINT index);
[added(10,0,15063,0)]
UINT64 GetString([out] LPCWSTR lpString, [in] UINT64 size, [in] UINT64 index);
};
class SimpleClass : ISimpleClass
{
};
}
The following example showcases how to define complex interfaces/classes that make use of more advanced XDL versioning features
import "unknown.xdl";
namespace gfx
{
struct GraphicsClassDesc
{
UINT TexturesCapacity;
[added(6,2,9200,0)] UINT ShadersCapacity;
[added(10,0,15063,0), removed(10,0,22000,0)] UINT ViewsCapacity;
[removed(10,0,18362,0)] UINT OpaqueDataCapacity;
};
[uuid("b54c4d35-8172-4575-9362-a614d34a834b")]
interface IGraphicsClass : IGraphicsUnknown
{
GraphicsClassDesc m_Desc;
HRESULT Initialize([in] IUnknown* pGraphicsDevice);
void GetDevice([out] IUnknown** ppGraphicsDevice);
[added(10,0,22000,0)]
HRESULT UpdateDevice(IUnknown* pGraphicsDevice);
};
class SomeGraphicsClass : IGraphicsClass
{
};
enum MemoryPressure
{
Low,
Medium,
High
};
struct MemoryInfo
{
UINT64 TotalAllocated;
UINT64 TotalFreed;
[conditional("defined(TRACK_MEMORY_PRESSURE)")]
MemoryPressure Pressure;
};
[uuid("1bc4eedb-9043-47ad-9572-590d1e50771b")]
interface IMemoryManager : IUnknown
{
HRESULT AllocateMemory([in] UINT64 size, [out] void** ppMemory);
[removed(10,0,22000,0)]
UINT64 GetTotalAllocatedMemory();
[removed(10,0,22000,0)]
UINT64 GetTotalFreedMemory();
[removed(10,0,22000,0)]
[conditional("defined(TRACK_MEMORY_PRESSURE)")]
MemoryPressure GetMemoryPressure();
[added(10,0,22000,0)]
void GetMemoryInfo([out] MemoryInfo* pMemoryInfo);
};
[uuid("a97f9933-9696-423d-9e2a-44c9cefbd058")]
interface IMemoryManager2 : [removed(10,0,26100,0)] IUnknown, [added(10,0,26100,0)] IMemoryManager
{
HRESULT FreeMemory([in] void* ppMemory);
};
class MemoryManager : [removed(10,0,26100,0)] IMemoryManager, [added(10,0,22631,0)] IMemoryManager2
{
};
}