Skip to content

Initializing ADLX with the ADLX Helpers

Navigation: Programming with ADLX → ADLX Programming Guide → Quick Start

It is recommended to load and initialize ADLX with ADLX Helper code. The ADLX Helper code has native support for C and C++. When programming in C#, Java, or Python, use the ADLX Helper code from the binding wrapper in the selected language to access ADLX.

To use ADLX in a C++ application

To access ADLX functionality from a C++ based application,

  • Start a new C++ application.
  • In the application, include the following files:

a. /SDK/ADLXHelper/Windows/Cpp/ADLXHelper.h

b. /SDK/ADLXHelper/Windows/Cpp/ADLXHelper.cpp

c. /SDK/Platform/Windows/WinAPIs.cpp

Result: Access to the IADLXSystem interface is provided.

Note: You can access the required ADLX functionality from the IADLXSystem interface.

  • Release all the interfaces obtained from ADLX.

Note: For interfaces held in a smart pointer, such as IADLXDisplayPtr for the IADLXDisplay interface, assign nullptr to release the interface.

Result: Resources utilized by ADLX are released, and the ADLX library is unloaded.

Warning: Step 6 must be completed before this step. Terminate unloads the ADLX library, so releasing an interface after this call - including a release performed implicitly by the destructor of a global or static smart pointer during process shutdown - dispatches into unloaded code and results in an access violation. See Interface lifetime in long-running applications.

For more information, see C++ samples.

To use ADLX in a C application

To access ADLX functionality from a C based application,

  • Start a new C application.
  • In the application, include the following files:

a. /SDK/ADLXHelper/Windows/C/ADLXHelper.h

b. /SDK/ADLXHelper/Windows/C/ADLXHelper.c

c. /SDK/Platform/Windows/WinAPIs.c

Result: Access to the IADLXSystem interface is provided.

Note: You can access the required ADLX functionality from the IADLXSystem interface.

  • Release all the interfaces obtained from ADLX by calling the Release method in each interface.
  • Call ADLXHelper_Terminate in the helper object to release the resources utilized by ADLX.

Result: The ADLX library is unloaded.

Warning: Step 5 must be completed before this step. ADLXHelper_Terminate unloads the ADLX library, so calling Release on an interface after this call dispatches into unloaded code and results in an access violation. See Interface lifetime in long-running applications.

For more information, see C samples.

To initialize ADLX in a C# application

Follow these steps to initialize ADLX in a C# application.

  • Start a new C# application.
  • Import all the *.cs files from the ADLX binding wrapper for C#.
  • Create an instance of the ADLXHelper class.
  • Call the Initialize method in the Helper object.
  • Call the GetSystemServices method in the Helper object.

Result: The IADLXSystem interface is accessible.

Note: The IADLXSystem interface provides access to ADLX functionality.

  • Release all the interfaces obtained from ADLX by calling the Release method in each interface.
  • Call Terminate in the Helper object.

Result: Resources utilized by ADLX are released, and the ADLX library is unloaded.

Warning: Step 6 must be completed before this step. An interface that is not released explicitly can be released after ADLX is terminated, which results in an access violation. See Interface lifetime in long-running applications.

For more information, see C# samples

To initialize ADLX in a Java application

Follow these steps to initialize ADLX in a Java application.

  • Start a new Java application.
  • Import all the Java files from the ADLX binding wrapper for Java.
  • Create an instance of the ADLXHelper class.
  • Call the Initialize method in the Helper object.
  • Call the GetSystemServices method in the Helper object.

Result: The IADLXSystem interface is accessible.

Note: The IADLXSystem interface provides access to ADLX functionality.

  • Release all the interfaces obtained from ADLX by calling the Release method in each interface.
  • Call Terminate in the Helper object.

Result: Resources utilized by ADLX are released, and the ADLX library is unloaded.

Warning: Step 6 must be completed before this step. Because the interfaces are finalized by the garbage collector at a time that is not controlled by the application, an interface that is not released explicitly can be released after ADLX is terminated, which results in an access violation. See Interface lifetime in long-running applications.

For more information, see Java samples.

To initialize ADLX in a Python application

Follow these steps to initialize ADLX in a Python application.

  • Start a new Python application.
  • Import the ADLXPybind.pyd package from the ADLX binding wrapper for Python.
  • Create an instance of the ADLXHelper class.
  • Call the Initialize method in the Helper object.
  • Call the GetSystemServices method in the Helper object.

Result: The IADLXSystem interface is accessible.

Note: The IADLXSystem interface provides access to ADLX functionality.

  • Release all the interfaces obtained from ADLX by discarding every reference to them, for example with del.
  • Call Terminate in the Helper object.

Result: Resources utilized by ADLX are released, and the ADLX library is unloaded.

Warning: Step 6 must be completed before this step. An interface that is still referenced when ADLX is terminated is released when the interpreter collects it, which happens after the termination and results in an access violation. Keeping the interfaces in module-level variables is not sufficient, because those are collected at interpreter shutdown. See Interface lifetime in long-running applications.

For more information, see Python samples.

Interface lifetime in long-running applications

All the interfaces obtained from ADLX must be released before ADLX is terminated. Terminating ADLX unloads the ADLX library, so an interface that is released afterwards dispatches into unloaded code and results in an access violation. The termination returns ADLX_OK in this case, and the crash occurs later, during process shutdown, which makes it appear unrelated to ADLX.

In a short program the correct order is obtained from the scope of the interfaces. The interfaces are local variables in main, so they are released when main returns, before the ADLXHelper instance is destroyed:

// ADLXHelper instance
// No outstanding interfaces from ADLX must exist when ADLX is destroyed.
// Use global variables to ensure validity of the interface.
static ADLXHelper g_ADLXHelp;
int main()
{
g_ADLXHelp.Initialize();
IADLXGPUListPtr gpus; // Local, released at the end of main
g_ADLXHelp.GetSystemServices()->GetGPUs(&gpus);
// ...
g_ADLXHelp.Terminate();
return 0;
}

This ordering does not carry over to an application that initializes ADLX at startup and terminates it from an unrelated shutdown path, because the interfaces are no longer local to the function that terminates ADLX. Such an application must release the interfaces explicitly. Note that the recommendation to keep the ADLXHelper instance in a global variable applies to the Helper only. Keeping the interfaces in global or static variables instead has the opposite effect, because their destruction order is not controlled by the application and can run after the termination:

// Correct: the Helper is global
static ADLXHelper g_ADLXHelp;
// Incorrect: these are released during process shutdown, after ADLX is terminated
static IADLXGPUListPtr g_gpus;
static IADLXPerformanceMonitoringServicesPtr g_perfMonitoringService;

To release the interfaces explicitly, assign nullptr to each smart pointer in a dedicated function, and call that function on every path that terminates ADLX. This includes the early-exit paths of a partially completed initialization, where some interfaces are already obtained and others are not:

static void ReleaseADLXInterfaces()
{
g_gpus = nullptr;
g_perfMonitoringService = nullptr;
}
void Shutdown()
{
ReleaseADLXInterfaces(); // Must precede the termination
g_ADLXHelp.Terminate();
}

For more information, see Interface lifetime sample and Interface lifetime sample in C.

API Reference

This page references: