Skip to content

Developing Xidi Plugins

Samuel Grossman edited this page Mar 29, 2026 · 1 revision

This document describes the various types of plugins for Xidi and how to create them. A Xidi plugin is simply a DLL that exports certain required functions and provides implementations of certain required Xidi interfaces, as described later in this document.

Getting Started

  1. If developing using tools other than Visual Studio 2022, ensure the Visual C++ Runtime for Visual Studio 2022 is installed. Xidi is linked against this runtime and will not run without it. If running a 64-bit operating system, install both the x86 and the x64 versions of this runtime, otherwise install just the x86 version.

  2. Download the latest release of Xidi and place the included header files into a directory accessible by whatever build system is being used to build Xidi plugins. Confnigure the plugin project's include paths accordingly. It is not necessary to link against any Xidi libraries.

Concepts

Plugin DLL files must be named "[Name].XidiPlugin.32.dll" (for a 32-bit plugin) or "[Name].XidiPlugin.64.dll" (for a 64-bit plugin).

All Xidi plugin implementations are derived from the common base IPlugin) interface type that Xidi defines. The individual types of plugins all define their own interface types that are derived from IPlugin. These interface types all provide a built-in non-overridable implementation of the PluginType method (so that the correct enumerator is automatically supplied to Xidi upon request). The remaining IPlugin methods, as well as any new methods introduced by these interface types, must be implemented by the plugin author.

A plugin DLL is permitted to contain within it multiple plugin implementations, each of which is identified by a name of the author's choice. When the user asks Xidi to load a plugin, they first identify the plugin by its DLL filename and then, second, identify the individual plugin implementation using the same string that is returned by the PluginName method. Xidi queries each loaded plugin DLL and enumerates all of the plugin interface implementations contained within it. It invokes the following two functions, defined in "Plugin.h" and which the plugin DLL must implement as entry points, to do so.

extern "C" int __fastcall XidiPluginGetCount(void);
extern "C" ::Xidi::IPlugin* __fastcall XidiPluginGetInterface(int index);

These functions do exactly as their names suggest. The XidiPluginGetCount returns the number of plugin interface implementations are contained in the plugin DLL, and the XidiPluginGetInterface function returns a plugin interface pointer for a specific plugin interface identified by zero-based index.

Types of Plugins

Xidi supports the types of plugins listed in the table below. The "required version" column indicates the released version of Xidi in which the plugin type was introduced and, hence, the minimum version of Xidi required to use plugins of that type.

Plugin Type Interface Required Version Description
Physical Controller Backend IPhysicalControllerBackend 5.0.0 Allows the mechanism by which Xidi communicates with physical controllers to be replaced. Xidi's built-in mechanism uses the official, documented XInput API.

The subsections that follow each describe the various plugin interfaces and how to implement them.

IPlugin

This is the base interface for all plugins. The methods below must be implemented by the plugin author, regardless of the type of plugin. Plugin authors must not override the PluginType method because all type-specific plugin interface types provide a built-in implementation that returns the correct EPluginType enumerator.

The code excerpt below summarizes how this interface is defined in the "PluginTypes.h" header file.

namespace Xidi
{
  enum class EPluginType : unsigned int
  {
    // Individual enumerators are not shown in this summary excerpt.
    Count
  };

  class IPlugin
  {
  public:
    virtual EPluginType PluginType(void) = 0;
    virtual std::wstring_view PluginName(void) = 0;
    virtual bool Initialize(void) = 0;
  };
}

PluginName

Xidi invokes this method to query the plugin interface for its name. The plugin author is free to choose a name, as long as it can be successfully parsed in a configuration file. This generally means that names should be alphanumeric but are additionally allowed to contain spaces and some basic punctuation.

Return Value

Name of the plugin interface implementation.

Notes

The string referenced by the returned view must remain constant and valid throughout the lifetime of the application. As a best practice, the name should be defined as a compile-time constant, such as a string literal.

Initialize

Invoked to give the plugin interface implementation an opportunity to initialize.

Return Value

true to indicate that initialization was successful, false otherwise. If initialization fails, Xidi will not use the plugin interface implementation.

Notes

All plugin types are allowed to initialize before they are used. As a matter of best practice, this is where any expensive initialization should occur, rather than in the constructor or the DLL entry point. That is because Xidi will unconditionally load all plugin DLL files that are requested in the configuration file and subsequently request interface pointers to all available plugin interfaces, but it will only initialize the specific plugin interfaces that it intends to use.

Plugins that do not require any explicit initialization should just return true from this method.

Examples

The "Examples" subdirectory of the Xidi source code shows a complete, working example of how to implement a plugin DLL.