
#ifndef DX_ETHERCAT_H
#define DX_ETHERCAT_H

#include "ethercat_types.h"
#include "internal/ordinals.h"
#include <stdint.h>
#include <string.h>

#include "data/types.h"
#include "data/structures.h"

#include "logging/logging.h"

#include "master/core.h"
#include "master/events.h"
#include "master/events_emcy.h"
#include "master/diagnostics.h"
#include "master/diagnostics_ext.h"
#include "master/diagnostics_info.h"
#include "master/config.h"
#include "master/mailbox_gateway.h"
#include "master/redundancy.h"
#include "master/hot_connect.h"
#include "master/state.h"
#include "master/other.h"
#include "master/master_od.h"

#include "slave/core.h"
#include "slave/coe.h"
#include "slave/coe_emcy.h"
#include "slave/soe.h"
#include "slave/eoe.h"
#include "slave/foe.h"
#include "slave/aoe.h"
#include "slave/voe.h"
#include "slave/fsoe.h"
#include "slave/dc.h"
#include "slave/pdo.h"
#include "slave/slave_pdo.h"
#include "slave/slave_stats.h"
#include "slave/cia401.h"
#include "slave/cia402.h"
#include "slave/mdp.h"
#include "slave/startup.h"
#include "slave/esi.h"
#include "slave/topology.h"
#include "slave/mbx_registry.h"

#include "statics/network.h"
#include "statics/print.h"
#include "statics/version.h"
#include "statics/version_info.h"
#include "statics/device_info.h"
#include "statics/other.h"
#include "statics/authorization.h"

#include "utils/base_data.h"
#include "utils/dll.h"
#include "utils/esi.h"
#include "utils/help.h"
#include "utils/slave_special_flags.h"
#include "utils/startup_verifier.h"
#include "utils/version_info.h"
#include "utils/xml.h"

#include "protocol/protocol_codes.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DYNAMIC_LOAD

#ifdef _WIN32
#include <windows.h>

#define DLL_HANDLE   HMODULE
#define LOAD_LIB(p)  LoadLibraryA(p)
#define GET_PROC(h,n) GetProcAddress(h,n)
#define FREE_LIB(h)  FreeLibrary(h)
#else
#include <dlfcn.h>

#define DLL_HANDLE   void*
#define LOAD_LIB(p)  dlopen(p, RTLD_NOW)
#define GET_PROC(h,n) dlsym(h,n)
#define FREE_LIB(h)  dlclose(h)
#endif

typedef uint16_t (*pfn_Initialize)(void);
typedef uint16_t (*pfn_InitializeSpecificMaster)(uint16_t);
typedef void     (*pfn_Dispose)(uint16_t);
typedef void     (*pfn_Start)(uint16_t);
typedef void     (*pfn_Stop)(uint16_t);
typedef int      (*pfn_GetMaxMasterInstances)(void);

typedef uint16_t (*pfn_SetNetwork)(uint16_t, const char*, const char*);
typedef BOOL     (*pfn_SetState)(uint16_t, int);
typedef BOOL     (*pfn_SetStateWithTimeout)(uint16_t, int, uint32_t);
typedef BOOL     (*pfn_SetSlaveStateWithTimeout)(uint16_t, uint16_t, int, uint32_t);
typedef BOOL     (*pfn_SetStateSequence)(uint16_t, int, uint32_t);
typedef BOOL     (*pfn_SetStateWithStartup)(uint16_t, int, uint32_t);
typedef uint8_t  (*pfn_GetLinkStatus)(uint16_t);
typedef uint8_t  (*pfn_GetSlaveState)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveALStatusCode)(uint16_t, uint16_t);

typedef uint8_t  (*pfn_GetIO)(uint16_t, uint16_t, int32_t*, uint8_t**, int32_t*, uint8_t**);
typedef void     (*pfn_LockIOmap)(uint16_t);
typedef void     (*pfn_UnlockIOmap)(uint16_t);
typedef void     (*pfn_WriteSlaveOutput)(uint16_t, uint16_t, const uint8_t*, uint32_t);
typedef void     (*pfn_WriteSlaveOutputByte)(uint16_t, uint16_t, uint32_t, uint8_t);
typedef void     (*pfn_SetMutexProtection)(uint16_t, BOOL);
typedef BOOL     (*pfn_GetMutexProtection)(uint16_t);

typedef uint8_t  (*pfn_SDOwrite)(uint16_t, uint16_t, uint16_t, uint8_t, BOOL, uint8_t*, int);
typedef char*    (*pfn_SDOread)(uint16_t, uint16_t, uint16_t, uint8_t, BOOL, int*);

typedef char*    (*pfn_SDOread_ex)(uint16_t mi, uint16_t slave, uint16_t index, uint8_t subindex,
                                    BOOL CA, int* outLen, uint32_t* outAbortCode);
typedef uint8_t  (*pfn_SDOwrite_ex)(uint16_t mi, uint16_t slave, uint16_t index, uint8_t subindex,
                                    BOOL CA, uint8_t* data, int len, uint32_t* outAbortCode);
typedef void*    (*pfn_GetSlaveSDOList)(uint16_t, uint16_t);
typedef void*    (*pfn_GetSlaveSDOListBasic)(uint16_t, uint16_t);
typedef void*    (*pfn_GetSlavePointer_SDO)(uint16_t, uint16_t, uint16_t);
typedef void*    (*pfn_GetSlavePointer_SDO_WithODList)(uint16_t, uint16_t, uint16_t, void*);

typedef void*    (*pfn_coe_get_od_list)(uint16_t mi, uint16_t si);
typedef void*    (*pfn_coe_get_object_desc)(uint16_t mi, uint16_t si, uint16_t index);
typedef void*    (*pfn_coe_get_entry_desc)(uint16_t mi, uint16_t si, uint16_t index, uint8_t subindex);
typedef void     (*pfn_coe_free_odlist)(void* p);
typedef void     (*pfn_coe_free_oelist)(void* p);
typedef char*    (*pfn_GetSlavePointer_SDO_Value)(uint16_t, uint16_t, uint16_t, uint8_t, int*);
typedef char*    (*pfn_GetSlavePointer_SDO_IndexValue)(uint16_t, uint16_t, uint16_t, uint8_t, int*);
typedef int      (*pfn_GetMultiSlaveSDOList)(uint16_t, uint16_t*, int, void**);
typedef void     (*pfn_FreeMultiSlaveSDOList)(void**, int);

typedef int      (*pfn_AddStartupParameter)(uint16_t, uint16_t, const ec_startup_param_t*);
typedef int      (*pfn_AddStartupParameterBatch)(uint16_t, uint16_t, const ec_startup_param_t*, int);
typedef int      (*pfn_ClearStartupParameters)(uint16_t, uint16_t);
typedef int      (*pfn_GetStartupParameterCount)(uint16_t, uint16_t);
typedef int      (*pfn_ApplyStartupParameters)(uint16_t, uint16_t, uint8_t, uint8_t);
typedef int      (*pfn_ApplyStartupParametersAll)(uint16_t, uint8_t, uint8_t);

typedef int      (*pfn_LoadConfigJson)(uint16_t, const char*);
typedef int      (*pfn_AutoConfigureSM)(uint16_t, uint16_t);
typedef uint16_t (*pfn_EcInit)(const char*);
typedef uint16_t (*pfn_EcInitFromFile)(const char*);
typedef void     (*pfn_EcClose)(uint16_t);

typedef void     (*pfn_SetMasterDCCycleTime)(uint16_t, uint32_t);
typedef void     (*pfn_SetMasterLoopCycleTime)(uint16_t, uint32_t);
typedef void     (*pfn_SetSyncBySlaveIndex)(uint16_t, uint16_t, uint32_t, uint32_t, int32_t);
typedef int      (*pfn_ConfigureDCAll)(uint16_t, uint32_t, uint32_t);
typedef int      (*pfn_UpdatePropagationDelays)(uint16_t);
typedef int      (*pfn_AutoCalculateDCShift)(uint16_t);
typedef void     (*pfn_EnableContinuousMeasurement)(uint16_t, BOOL, uint32_t);
typedef void     (*pfn_EnableDriftCompensation)(uint16_t, BOOL, int32_t, int32_t);
typedef void     (*pfn_SetDCAutoShiftEnabled)(uint16_t, BOOL);
typedef BOOL     (*pfn_GetDCAutoShiftEnabled)(uint16_t);
typedef int32_t  (*pfn_GetSlavePropagationDelay)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetMaxPropagationDelay)(uint16_t);
typedef BOOL     (*pfn_GetSlaveSyncWindowStatus)(uint16_t, uint16_t, int*, int*, int*, BOOL*, uint32_t*);
typedef void     (*pfn_SetSyncWindowThreshold)(uint16_t, int);
typedef int      (*pfn_GetSyncWindowThreshold)(uint16_t);
typedef void     (*pfn_ResetSlaveSyncWindowStats)(uint16_t, uint16_t);
typedef int      (*pfn_GetMaxSyncDifference)(uint16_t);
typedef BOOL     (*pfn_IsAllSlavesInSync)(uint16_t);

typedef BOOL     (*pfn_SetSlaveGroup)(uint16_t, uint16_t, uint8_t);
typedef uint8_t  (*pfn_GetSlaveGroup)(uint16_t, uint16_t);
typedef BOOL     (*pfn_SetGroupCycleDivider)(uint16_t, uint8_t, uint8_t);
typedef uint8_t  (*pfn_GetGroupCycleDivider)(uint16_t, uint8_t);
typedef BOOL     (*pfn_SetGroupEnabled)(uint16_t, uint8_t, BOOL);
typedef BOOL     (*pfn_GetGroupEnabled)(uint16_t, uint8_t);
typedef uint16_t (*pfn_GetGroupExpectedWKC)(uint16_t, uint8_t);
typedef uint8_t  (*pfn_GetActiveGroupCount)(uint16_t);
typedef uint16_t (*pfn_GetGroupSlaveCount)(uint16_t, uint8_t);

typedef BOOL     (*pfn_SoERead)(uint16_t, uint16_t, uint8_t, uint8_t, uint16_t, char**, int*, int);
typedef BOOL     (*pfn_SoEWrite)(uint16_t, uint16_t, uint8_t, uint8_t, uint16_t, const char*, int, int);
typedef BOOL     (*pfn_SoEReadAttributes)(uint16_t, uint16_t, uint8_t, uint16_t, uint32_t*, int);
typedef BOOL     (*pfn_SoEReadName)(uint16_t, uint16_t, uint8_t, uint16_t, char**, int*, int);
typedef BOOL     (*pfn_SoEReadUnit)(uint16_t, uint16_t, uint8_t, uint16_t, char**, int*, int);
typedef BOOL     (*pfn_SoEReadIDNList)(uint16_t, uint16_t, uint8_t, uint16_t**, int*, int);
typedef BOOL     (*pfn_SoEReadMinMax)(uint16_t, uint16_t, uint8_t, uint16_t, char**, int*, char**, int*, int);

typedef BOOL     (*pfn_FOERead)(uint16_t, uint16_t, const char*, uint32_t, char**, int*, int);
typedef BOOL     (*pfn_FOEWrite)(uint16_t, uint16_t, const char*, uint32_t, const char*, int, int);
typedef BOOL     (*pfn_FOEReadEx)(uint16_t, uint16_t, const char*, uint32_t, char**, int*, int, ec_foe_options_t*);
typedef BOOL     (*pfn_FOEWriteEx)(uint16_t, uint16_t, const char*, uint32_t, const char*, int, int, ec_foe_options_t*);
typedef BOOL     (*pfn_FOESetProgressHook)(uint16_t, foe_progress_callback_t);
typedef BOOL     (*pfn_FOEClearProgressHook)(uint16_t);

typedef BOOL     (*pfn_EOESetIP)(uint16_t, uint16_t, uint8_t, uint32_t, uint32_t, uint32_t, int);
typedef BOOL     (*pfn_EOEGetIP)(uint16_t, uint16_t, uint8_t, uint32_t*, uint32_t*, uint32_t*, int);
typedef BOOL     (*pfn_EOESendFrame)(uint16_t, uint16_t, uint8_t, const uint8_t*, int, int);
typedef BOOL     (*pfn_EOEReceiveFrame)(uint16_t, uint16_t, uint8_t, uint8_t**, int*, int);
typedef BOOL     (*pfn_EOESetMAC)(uint16_t, uint16_t, uint8_t, const uint8_t*, int);
typedef BOOL     (*pfn_EOEGetMAC)(uint16_t, uint16_t, uint8_t, uint8_t*, int);
typedef BOOL     (*pfn_EOESetDNS)(uint16_t, uint16_t, uint8_t, uint32_t, const char*, int);
typedef BOOL     (*pfn_EOEGetDNS)(uint16_t, uint16_t, uint8_t, uint32_t*, char*, int);
typedef BOOL     (*pfn_EOEGetFullParam)(uint16_t, uint16_t, uint8_t, uint32_t*, uint32_t*, uint32_t*, uint8_t*, uint32_t*, char*, int);
typedef BOOL     (*pfn_EOESetFullParam)(uint16_t, uint16_t, uint8_t, uint32_t, uint32_t, uint32_t, const uint8_t*, uint32_t, const char*, int);
typedef BOOL     (*pfn_EOESetAddressFilter)(uint16_t, uint16_t, uint8_t, uint8_t, const uint8_t*, int);
typedef BOOL     (*pfn_EOEGetAddressFilter)(uint16_t, uint16_t, uint8_t, uint8_t*, uint8_t*, int, int);

typedef BOOL     (*pfn_AOESendCommand)(uint16_t, uint16_t, uint16_t, uint16_t, const uint8_t*, uint32_t, uint8_t**, uint32_t*, int);
typedef BOOL     (*pfn_AOEReadWrite)(uint16_t, uint16_t, uint32_t, uint32_t, uint32_t, uint32_t, const uint8_t*, uint8_t**, uint32_t*, int);
typedef BOOL     (*pfn_AOEReadDeviceInfo)(uint16_t, uint16_t, uint8_t*, uint8_t*, uint16_t*, char*, int, int);
typedef BOOL     (*pfn_AOEReadState)(uint16_t, uint16_t, uint16_t*, uint16_t*, int);
typedef BOOL     (*pfn_AOEWriteControl)(uint16_t, uint16_t, uint16_t, uint16_t, const uint8_t*, int, int);
typedef BOOL     (*pfn_AOEAddNotification)(uint16_t, uint16_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t*, int);
typedef BOOL     (*pfn_AOEDelNotification)(uint16_t, uint16_t, uint32_t, int);
typedef BOOL     (*pfn_AOESetConfig)(uint16_t, uint16_t, const uint8_t*, uint16_t, const uint8_t*, uint16_t);
typedef BOOL     (*pfn_AOEGetConfig)(uint16_t, uint16_t, uint8_t*, uint16_t*, uint8_t*, uint16_t*);
typedef BOOL     (*pfn_AOEStartNotificationListener)(uint16_t);
typedef BOOL     (*pfn_AOEStopNotificationListener)(void);
typedef BOOL     (*pfn_AOEIsNotificationListening)(void);
typedef int      (*pfn_AOERegisterNotification)(uint16_t, uint32_t, uint32_t, uint32_t, uint32_t, aoe_notification_callback_t, void*);
typedef BOOL     (*pfn_AOEUnregisterNotification)(int);

typedef BOOL     (*pfn_VOESend)(uint16_t, uint16_t, uint32_t, uint16_t, const uint8_t*, int, int);
typedef BOOL     (*pfn_VOEReceive)(uint16_t, uint16_t, uint32_t*, uint16_t*, uint8_t**, int*, int);
typedef BOOL     (*pfn_VOESendRaw)(uint16_t, uint16_t, const uint8_t*, int, int);
typedef BOOL     (*pfn_VOEReceiveRaw)(uint16_t, uint16_t, uint8_t**, int*, int);
typedef BOOL     (*pfn_VOEIsSupported)(uint16_t, uint16_t);

typedef void     (*pfn_SetLogCallback)(log_callback_t);
typedef void     (*pfn_SetCrashCallback)(crash_callback_t);
typedef void     (*pfn_RegisterProcessDataCyclicCallbackSync)(pdo_cyclic_callback_t);

typedef void     (*pfn_RegisterSlaveStateChangeCallbackSync)(state_change_callback_t);
typedef void     (*pfn_RegisterSlaveStateChangeCallbackAsync)(state_change_callback_t);
typedef void     (*pfn_RegisterEmergencyEventCallback)(emergency_callback_t);
typedef void     (*pfn_RegisterSlaveDiscoveryCallbackSync)(discovery_callback_t);
typedef void     (*pfn_RegisterSlaveDiscoveryCallbackAsync)(discovery_callback_t);
typedef void     (*pfn_RegisterPDOFrameLossCallback)(frame_loss_callback_t);
typedef void     (*pfn_RegisterRedundancyModeChangedCallback)(redundancy_changed_callback_t);
typedef void     (*pfn_RegisterSlavePreOpReconfigCallback)(preop_reconfig_callback_t);

typedef void     (*pfn_SetDCSyncLostCallback)(dc_sync_lost_callback_t);
typedef void     (*pfn_RegisterSlaveIdentityMismatchCallback)(identity_mismatch_callback_t);
typedef void     (*pfn_RegisterSlavePortLinkChangedCallback)(port_link_changed_callback_t);

typedef pfn_RegisterProcessDataCyclicCallbackSync   pfn_RegisterPDOCyclicSync;

typedef pfn_RegisterSlaveStateChangeCallbackSync    pfn_RegisterStateChangeSync;
typedef pfn_RegisterSlaveStateChangeCallbackAsync   pfn_RegisterStateChangeAsync;
typedef pfn_RegisterEmergencyEventCallback          pfn_RegisterEmergency;
typedef pfn_RegisterSlaveDiscoveryCallbackSync      pfn_RegisterDiscoverySync;
typedef pfn_RegisterSlaveDiscoveryCallbackAsync     pfn_RegisterDiscoveryAsync;
typedef pfn_RegisterPDOFrameLossCallback            pfn_RegisterPDOFrameLoss;
typedef pfn_RegisterRedundancyModeChangedCallback   pfn_RegisterRedundancyChanged;
typedef pfn_RegisterSlavePreOpReconfigCallback      pfn_RegisterPreOpReconfig;

typedef pfn_RegisterSlaveIdentityMismatchCallback   pfn_RegisterSlaveIdentityMismatch;
typedef pfn_RegisterSlavePortLinkChangedCallback    pfn_RegisterSlavePortLinkChanged;

typedef BOOL     (*pfn_AcknowledgeSlaveReplacement)(uint16_t, uint16_t);

typedef BOOL     (*pfn_WriteSlaveDLPORT)(uint16_t, uint16_t, uint8_t);
typedef BOOL     (*pfn_ReadSlaveDLPORT)(uint16_t, uint16_t, uint8_t*);

typedef void*    (*pfn_GetMasterState)(uint16_t);
typedef void*    (*pfn_GetMasterStateCache)(uint16_t);
typedef void*    (*pfn_GetSlave)(uint16_t, uint16_t);
typedef void*    (*pfn_GetSlaveDetailedInfo)(uint16_t, uint16_t);
typedef void*    (*pfn_GetCommunicationStats)(uint16_t);
typedef void     (*pfn_ResetCommunicationStats)(uint16_t);
typedef void*    (*pfn_GetDetailedDiagnostics)(uint16_t);
typedef void     (*pfn_ResetDiagnostics)(uint16_t);
typedef const void* (*pfn_GetDiagnosticsPointer)(uint16_t);
typedef const void* (*pfn_GetSummaryPointer)(uint16_t);
typedef void     (*pfn_SetDiagnosticsEnabled)(uint16_t, BOOL);
typedef BOOL     (*pfn_GetDiagnosticsEnabled)(uint16_t);
typedef uint16_t (*pfn_GetExpectedWKC)(uint16_t);

typedef float    (*pfn_GetPacketLossRate)(uint16_t);
typedef float    (*pfn_GetLateFrameRate)(uint16_t);
typedef uint32_t (*pfn_GetWdkPrimaryFrameTx)(uint16_t);
typedef uint32_t (*pfn_GetWdkPrimaryFrameRx)(uint16_t);
typedef uint32_t (*pfn_GetWdkSecondaryFrameTx)(uint16_t);
typedef uint32_t (*pfn_GetWdkSecondaryFrameRx)(uint16_t);
typedef uint32_t (*pfn_GetWdkPdoIdxDropCount)(uint16_t);
typedef void     (*pfn_SetExpectedWKC)(uint16_t, uint16_t);
typedef int16_t  (*pfn_GetSlaveLinkQuality)(uint16_t, uint16_t);

typedef void     (*pfn_RecordPDOCycleStart)(uint16_t);
typedef void     (*pfn_RecordWKC)(uint16_t, uint16_t);
typedef void     (*pfn_UpdateDiagnosticsSnapshot)(uint16_t);
typedef BOOL     (*pfn_ResetSlavePortErrorCounters)(uint16_t, uint16_t);
typedef const version_info_t* (*pfn_GetDllVersionInfo)(void);

#pragma pack(push, 4)
typedef struct {
    uint32_t major;
    uint32_t minor;
    uint32_t build;
    char     build_date[32];
    char     driver_name[32];
    uint32_t available;
    uint32_t error_code;
} driver_version_info_t;
#pragma pack(pop)
typedef const driver_version_info_t* (*pfn_GetDriverVersion)(void);
typedef void (*pfn_InvalidateDriverVersionCache)(void);
typedef int  (*pfn_EnsureDriversRunning)(void);
typedef void     (*pfn_DumpSlaveStructOffsets)(void);

typedef BOOL     (*pfn_GetMasterIdentity)(uint16_t, ec_master_identity_t*);
typedef BOOL     (*pfn_GetMasterDiagData)(uint16_t, ec_master_diag_data_t*);
typedef int      (*pfn_ec_validate_config)(uint16_t);
typedef int      (*pfn_ec_perf_export_csv)(uint16_t, const char*);
typedef int      (*pfn_GetBreakPoints)(uint16_t, uint16_t*, uint8_t*, uint8_t*, uint16_t);
typedef int      (*pfn_GetRingMode)(uint16_t);
typedef BOOL     (*pfn_GetSecondaryLinkStatus)(uint16_t);
typedef BOOL     (*pfn_ReadSlavePortErrorCounters)(uint16_t, uint16_t, uint8_t*, uint8_t*, uint8_t*);
typedef int      (*pfn_ReadAllSlavePortErrorCounters)(uint16_t);
typedef void*    (*pfn_GetSlavePortErrorStats)(uint16_t, uint16_t);
typedef void     (*pfn_UpdateDiagnosticsWithESCErrors)(uint16_t);
typedef BOOL     (*pfn_GetDiagnosticsSnapshot)(uint16_t, ec_diagnostics_snapshot_t*);

typedef uint8_t  (*pfn_GetSlaveWcState)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveAlStatusMirror)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetWcDeficit)(uint16_t);
typedef uint64_t (*pfn_GetWcStateSeq)(uint16_t);
typedef uint16_t (*pfn_GetMappedSlaveCount)(uint16_t);
typedef uint16_t (*pfn_GetWkcActualMirror)(uint16_t);
typedef uint16_t (*pfn_GetWkcExpectedMirror)(uint16_t);

typedef int          (*pfn_DarraEcat_KernelProbe)(void);
typedef const char*  (*pfn_DarraEcat_KernelStatusMessage)(int);
typedef const char*  (*pfn_DarraEcat_KernelInstallerUrl)(void);

typedef void*    (*pfn_GetCycleEventHandle)(uint16_t);
typedef const char* (*pfn_GetCycleEventName)(uint16_t);
typedef BOOL     (*pfn_WaitForCycleEvent)(uint16_t, uint32_t);
typedef uint64_t (*pfn_GetCycleCount)(uint16_t);

typedef void (*pfn_UnregisterProcessDataCyclicCallbackSync)(pdo_cyclic_callback_t);

typedef void (*pfn_UnregisterSlaveStateChangeCallbackSync)(state_change_callback_t);
typedef void (*pfn_UnregisterSlaveStateChangeCallbackAsync)(state_change_callback_t);
typedef void (*pfn_UnregisterEmergencyEventCallback)(emergency_callback_t);
typedef void (*pfn_UnregisterSlaveDiscoveryCallbackSync)(discovery_callback_t);
typedef void (*pfn_UnregisterSlaveDiscoveryCallbackAsync)(discovery_callback_t);
typedef void (*pfn_UnregisterPDOFrameLossCallback)(frame_loss_callback_t);
typedef void (*pfn_UnregisterRedundancyModeChangedCallback)(redundancy_changed_callback_t);
typedef void (*pfn_UnregisterSlavePreOpReconfigCallback)(preop_reconfig_callback_t);
typedef void (*pfn_UnregisterSlaveIdentityMismatchCallback)(identity_mismatch_callback_t);

typedef void (*pfn_UnregisterSlavePortLinkChangedCallback)(port_link_changed_callback_t);
typedef void (*pfn_UnsetLogCallback)(log_callback_t);
typedef void (*pfn_UnsetCrashCallback)(crash_callback_t);
typedef void (*pfn_UnsetDCSyncLostCallback)(dc_sync_lost_callback_t);

typedef const char* (*pfn_AL_StatusCode_GetDescriptionChinese)(uint16_t);
typedef const char* (*pfn_AL_StatusCode_GetRecoveryHintChinese)(uint16_t);

typedef void     (*pfn_GetMasterAlstatRefresh)(uint16_t, uint64_t*, uint16_t*, uint16_t*);
typedef void     (*pfn_GetPiggybackDiagCounters)(uint32_t*, uint32_t*, uint32_t*, uint32_t*, uint32_t*);
typedef void     (*pfn_GetPiggybackDiagCounters2)(uint32_t*, uint32_t*, uint32_t*, uint32_t*);
typedef uint16_t (*pfn_GetTopoPriIntact)(uint16_t);
typedef uint16_t (*pfn_GetTopoSecIntact)(uint16_t);

typedef int      (*pfn_HotSwapRebuild)(uint16_t);

typedef uint8_t  (*pfn_GetSlaveFreeRunDemoted)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveMailboxHealth)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveHealthDegradedCount)(uint16_t, uint16_t);
typedef BOOL     (*pfn_RecoverSlaveMailboxHealth)(uint16_t, uint16_t);

typedef uint64_t (*pfn_GetRtPreemptCount)(uint16_t);
typedef uint32_t (*pfn_GetRtPreemptPeakNs)(uint16_t);
typedef uint64_t (*pfn_GetBigGapUnknownCount)(uint16_t);
typedef uint32_t (*pfn_GetSmiMsrAvailable)(uint16_t);
typedef int      (*pfn_GetWdkRtCpuIndex)(uint16_t);
typedef int      (*pfn_GetWdkRxCpuIndex)(uint16_t);
typedef uint32_t (*pfn_GetWdkJitterInstrumentVer)(uint16_t);
typedef uint32_t (*pfn_GetWdkJitterHistBin)(uint16_t, uint32_t);
typedef uint64_t (*pfn_GetWdkJitterTotalSamples)(uint16_t);
typedef uint32_t (*pfn_GetWdkJitterMinNs)(uint16_t);
typedef int32_t  (*pfn_GetWdkJitterLastWakeDeltaNs)(uint16_t);
typedef uint32_t (*pfn_GetWdkPathCountFast)(uint16_t);
typedef uint32_t (*pfn_GetWdkPathCountMed)(uint16_t);
typedef uint32_t (*pfn_GetWdkPathCountSlow)(uint16_t);
typedef uint32_t (*pfn_GetWdkKtimerWakeNormalCnt)(uint16_t);
typedef uint32_t (*pfn_GetWdkKtimerWakeOverrunCnt)(uint16_t);
typedef uint32_t (*pfn_GetWdkDispatchCycleMaxJitterNs)(uint16_t);
typedef uint32_t (*pfn_GetWdkDrainCycleMaxJitterNs)(uint16_t);
typedef uint32_t (*pfn_GetWdkDiagCounter)(uint16_t, uint32_t);

typedef void     (*pfn_ClearAllEvents)(uint16_t);

typedef int      (*pfn_SDOReadMultiple)(uint16_t, uint16_t, const ec_sdo_entry_t*, int, ec_sdo_read_result_t*);

typedef int      (*pfn_GetNetworkInfo)(BOOL, BOOL);
typedef void*    (*pfn_GetNetworksPointer)(void);
typedef int      (*pfn_QuickSlaveCount)(const char*);
typedef int      (*pfn_QuickFindRedundantPairBatch)(const char**, int, int*, int*, int*, int*);

typedef int      (*pfn_ReadSlaveInfo)(const char*);
typedef int      (*pfn_GetScannedSlaveCount)(void);
typedef BOOL     (*pfn_GetScannedSlaveInfo)(int, uint32_t*, uint32_t*, uint32_t*, uint32_t*, char*, int, uint16_t*, uint16_t*, uint16_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
typedef int      (*pfn_GetRingSlaveCount)(void);

typedef int      (*pfn_GetAvailableCpuCores)(void);
typedef BOOL     (*pfn_SetMasterCpuAffinity)(uint16_t, int);
typedef BOOL     (*pfn_SetProcessCpuAffinity)(int);
typedef BOOL     (*pfn_SetPDOThreadCpuAffinity)(uint16_t, int);
typedef int      (*pfn_GetPDOThreadCpuAffinity)(uint16_t);
typedef BOOL     (*pfn_ApplyRealtimeOptimizations)(void);
typedef BOOL     (*pfn_RemoveRealtimeOptimizations)(void);
typedef BOOL     (*pfn_GetRealtimeOptimizationsStatus)(void);
typedef uint32_t (*pfn_GetTimingMode)(uint16_t);
typedef int      (*pfn_DarraValidateTimerAccuracy)(uint32_t, uint32_t);

typedef void     (*pfn_SetRedProcessdata)(int);
typedef int      (*pfn_GetRedProcessdata)(void);
typedef BOOL     (*pfn_EnableRedundancy)(uint16_t, BOOL);
typedef void*    (*pfn_GetRedundancyStatus)(uint16_t);
typedef BOOL     (*pfn_ForceRedundancyFailover)(uint16_t);
typedef BOOL     (*pfn_CheckRedundancyHealth)(uint16_t);

typedef BOOL     (*pfn_WriteSlaveRegister)(uint16_t, uint16_t, uint16_t, uint8_t*, uint32_t);
typedef BOOL     (*pfn_ReadSlaveRegister)(uint16_t, uint16_t, uint16_t, uint8_t*, uint32_t);
typedef BOOL     (*pfn_ConfigureSyncManager)(uint16_t, uint16_t, uint8_t, uint16_t, uint16_t, uint8_t, BOOL);
typedef BOOL     (*pfn_ConfigureFMMU)(uint16_t, uint16_t, uint8_t, uint32_t, uint16_t, uint8_t, uint8_t, uint16_t, uint8_t, uint8_t, BOOL);
typedef BOOL     (*pfn_EnableOutputSyncManager)(uint16_t, uint16_t);
typedef BOOL     (*pfn_DisableOutputSyncManager)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveOpOnlyFlag)(uint16_t, uint16_t);
typedef BOOL     (*pfn_SetSlaveErrorAck)(uint16_t, uint16_t, BOOL);
typedef BOOL     (*pfn_GetSlaveDeviceEmulationFlag)(uint16_t, uint16_t);

typedef int      (*pfn_SIIReadWord)(uint16_t, uint16_t, uint16_t, uint16_t*);
typedef int      (*pfn_SIIWriteWord)(uint16_t, uint16_t, uint16_t, uint16_t);

typedef BOOL     (*pfn_SetSlaveWatchdog)(uint16_t, uint16_t, uint32_t);
typedef BOOL     (*pfn_SetSlavePdiWatchdog)(uint16_t, uint16_t, uint32_t);
typedef BOOL     (*pfn_GetSlaveWatchdogConfig)(uint16_t, uint16_t, ec_watchdog_config_t*);
typedef BOOL     (*pfn_GetSlaveWatchdogStatus)(uint16_t, uint16_t, ec_watchdog_status_t*);
typedef int      (*pfn_SetAllSlaveWatchdog)(uint16_t, uint32_t);
typedef int      (*pfn_SetAllSlavePdiWatchdog)(uint16_t, uint32_t);

typedef BOOL     (*pfn_GetSlaveIdentity)(uint16_t, uint16_t, ec_slave_identity_t*);
typedef BOOL     (*pfn_VerifySlaveIdentity)(uint16_t, uint16_t, ec_slave_identity_t*, BOOL, BOOL);
typedef BOOL     (*pfn_VerifyAllSlaveIdentities)(uint16_t, ec_slave_identity_t*, uint32_t, BOOL, BOOL, uint64_t*);
typedef BOOL     (*pfn_SetSlaveOptional)(uint16_t, uint16_t, BOOL);
typedef BOOL     (*pfn_GetSlaveOptional)(uint16_t, uint16_t);
typedef BOOL     (*pfn_SetSlaveSupportsFrameRepeat)(uint16_t, uint16_t, BOOL);
typedef BOOL     (*pfn_GetSlaveSupportsFrameRepeat)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveNeedsStartupReconfig)(uint16_t, uint16_t);
typedef void     (*pfn_ClearSlaveNeedsStartupReconfig)(uint16_t, uint16_t);

typedef BOOL     (*pfn_GetSlaveEsmTimeouts)(uint16_t, uint16_t, ec_esm_timeouts_t*);
typedef BOOL     (*pfn_SetSlaveEsmTimeouts)(uint16_t, uint16_t, ec_esm_timeouts_t*);

typedef void     (*pfn_SetPDOLogging)(BOOL);
typedef void     (*pfn_SetMailboxLogging)(BOOL);
typedef void     (*pfn_SetDebugLogging)(BOOL);
typedef void     (*pfn_CloseDebugLog)(void);

typedef uint16_t (*pfn_GetPrimaryWKC)(void);
typedef uint16_t (*pfn_GetSecondaryWKC)(void);
typedef uint16_t (*pfn_GetPrimaryWKCEx)(uint16_t);
typedef uint16_t (*pfn_GetSecondaryWKCEx)(uint16_t);

typedef void     (*pfn_FreeMemory)(void*);

typedef BOOL     (*pfn_IsWdkAvailable)(uint16_t);
typedef BOOL     (*pfn_SetWdkMode)(uint16_t, BOOL);
typedef BOOL     (*pfn_GetWdkMode)(uint16_t);
typedef BOOL     (*pfn_StartWdkRT)(uint16_t, uint32_t, uint32_t);
typedef BOOL     (*pfn_StopWdkRT)(uint16_t);

typedef BOOL     (*pfn_SetWdkPdOffload)(uint16_t, BOOL, const uint8_t*, uint32_t,
                                        uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
typedef BOOL     (*pfn_PiggybackRequest)(uint16_t, const uint8_t*, uint32_t);
typedef BOOL     (*pfn_PiggybackResponse)(uint16_t, uint8_t*, uint32_t, uint32_t*);

typedef uint8_t  (*pfn_GetSlaveStateLive)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveALStatusCodeLive)(uint16_t, uint16_t);

typedef void     (*pfn_SetLicenseExpiredCallback)(license_expired_callback_t);
typedef void     (*pfn_UnsetLicenseExpiredCallback)(license_expired_callback_t);

typedef BOOL     (*pfn_SetUdpMode)(uint16_t, BOOL);
typedef BOOL     (*pfn_GetUdpMode)(uint16_t);
typedef BOOL     (*pfn_IsUdpAvailable)(uint16_t);

typedef void     (*pfn_AbortScan)(void);
typedef void     (*pfn_ResetScanAbort)(void);
typedef void     (*pfn_AbortNetwork)(void);
typedef void     (*pfn_ResetAbortNetwork)(void);
typedef void     (*pfn_EmergencyCloseNics)(void);

typedef cia402_state_t (*pfn_CiA402_ParseState)(uint16_t);
typedef uint16_t (*pfn_CiA402_GetEnableCommand)(uint16_t);
typedef int      (*pfn_CiA402_SetMode)(uint16_t, uint16_t, int8_t);
typedef int8_t   (*pfn_CiA402_GetMode)(uint16_t, uint16_t);
typedef uint16_t (*pfn_CiA402_ReadStatusWord)(uint16_t, uint16_t);
typedef int      (*pfn_CiA402_WriteControlWord)(uint16_t, uint16_t, uint16_t);
typedef int      (*pfn_CiA402_Enable)(uint16_t, uint16_t, int);
typedef int      (*pfn_CiA402_FaultReset)(uint16_t, uint16_t);

typedef int      (*pfn_EmcyGetHistory)(uint16_t, uint16_t, ec_emcy_record_t*, int);
typedef void     (*pfn_EmcyClearHistory)(uint16_t, uint16_t);
typedef int      (*pfn_EmcyGetCount)(uint16_t, uint16_t);

typedef void     (*pfn_PdoWriteInt8)(uint16_t, uint16_t, uint32_t, int8_t);
typedef void     (*pfn_PdoWriteInt16)(uint16_t, uint16_t, uint32_t, int16_t);
typedef void     (*pfn_PdoWriteInt32)(uint16_t, uint16_t, uint32_t, int32_t);
typedef void     (*pfn_PdoWriteUint8)(uint16_t, uint16_t, uint32_t, uint8_t);
typedef void     (*pfn_PdoWriteUint16)(uint16_t, uint16_t, uint32_t, uint16_t);
typedef void     (*pfn_PdoWriteUint32)(uint16_t, uint16_t, uint32_t, uint32_t);
typedef int8_t   (*pfn_PdoReadInt8)(uint16_t, uint16_t, uint32_t);
typedef int16_t  (*pfn_PdoReadInt16)(uint16_t, uint16_t, uint32_t);
typedef int32_t  (*pfn_PdoReadInt32)(uint16_t, uint16_t, uint32_t);
typedef uint8_t  (*pfn_PdoReadUint8)(uint16_t, uint16_t, uint32_t);
typedef uint16_t (*pfn_PdoReadUint16)(uint16_t, uint16_t, uint32_t);
typedef uint32_t (*pfn_PdoReadUint32)(uint16_t, uint16_t, uint32_t);

typedef uint8_t  (*pfn_PDOReadInputU8)(uint16_t, uint16_t, uint32_t);
typedef int16_t  (*pfn_PDOReadInputI16)(uint16_t, uint16_t, uint32_t);
typedef uint16_t (*pfn_PDOReadInputU16)(uint16_t, uint16_t, uint32_t);
typedef int32_t  (*pfn_PDOReadInputI32)(uint16_t, uint16_t, uint32_t);
typedef uint32_t (*pfn_PDOReadInputU32)(uint16_t, uint16_t, uint32_t);
typedef float    (*pfn_PDOReadInputF32)(uint16_t, uint16_t, uint32_t);
typedef BOOL     (*pfn_PDOWriteOutputU8)(uint16_t, uint16_t, uint32_t, uint8_t);
typedef BOOL     (*pfn_PDOWriteOutputI16)(uint16_t, uint16_t, uint32_t, int16_t);
typedef BOOL     (*pfn_PDOWriteOutputU16)(uint16_t, uint16_t, uint32_t, uint16_t);
typedef BOOL     (*pfn_PDOWriteOutputI32)(uint16_t, uint16_t, uint32_t, int32_t);
typedef BOOL     (*pfn_PDOWriteOutputU32)(uint16_t, uint16_t, uint32_t, uint32_t);
typedef BOOL     (*pfn_PDOWriteOutputF32)(uint16_t, uint16_t, uint32_t, float);

typedef BOOL     (*pfn_PDOReadDirect)(uint16_t, uint16_t, uint16_t, void*, uint32_t, uint32_t*);
typedef BOOL     (*pfn_PDOWriteDirect)(uint16_t, uint16_t, uint16_t, const void*, uint32_t);
typedef uint32_t (*pfn_PDOBatchRead)(uint16_t, uint16_t*, uint32_t, void**, uint32_t*, uint32_t*);
typedef uint32_t (*pfn_PDOBatchWrite)(uint16_t, uint16_t*, uint32_t, const void**, uint32_t*);
typedef void*    (*pfn_GetPDOStats)(uint16_t, uint16_t);
typedef void     (*pfn_ResetPDOStats)(uint16_t, uint16_t);
typedef void     (*pfn_EnablePDOMonitoring)(BOOL);
typedef BOOL     (*pfn_IsPDOMonitoringEnabled)(void);

typedef BOOL     (*pfn_GetPDOMapping)(uint16_t, uint16_t, uint16_t, void*, uint32_t, uint32_t*);
typedef void     (*pfn_GetPDOFrameLossStats)(uint16_t, uint8_t, uint32_t*, uint32_t*, uint32_t*);
typedef void     (*pfn_ResetPDOFrameLossStats)(uint16_t, uint8_t);

typedef int      (*pfn_mbx_get_stats_by_master)(uint16_t, uint16_t, uint8_t, ec_mbx_stats_t*);
typedef void     (*pfn_mbx_reset_stats_by_master)(uint16_t, uint16_t, uint8_t);
typedef int      (*pfn_mbx_submit_async_by_master)(uint16_t, ec_mbx_transaction_t*, uint32_t*);
typedef int      (*pfn_mbx_wait_by_master)(uint16_t, uint32_t, int);
typedef int      (*pfn_mbx_cancel_by_master)(uint16_t, uint32_t);
typedef int      (*pfn_mbx_get_result_by_master)(uint16_t, uint32_t, ec_mbx_transaction_t*);

typedef int      (*pfn_GetTopology)(uint16_t, ec_topology_node_t*, int);
typedef int      (*pfn_TopologyBuild)(uint16_t, ec_topology_node_t*, int);
typedef int      (*pfn_TopologyGetChildren)(uint16_t, uint16_t, uint16_t*, int);
typedef int      (*pfn_TopologyGetRoots)(uint16_t, uint16_t*, int);
typedef uint8_t  (*pfn_GetSlaveActivePorts)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveParent)(uint16_t, uint16_t);

typedef char*    (*pfn_GetSerialNumber)(void);
typedef char*    (*pfn_GetDeviceName)(void);
typedef char*    (*pfn_GetUserEmail)(void);
typedef char*    (*pfn_GetWindowsProductKey)(void);
typedef char*    (*pfn_GetDriverList)(void);
typedef int      (*pfn_VerifyLicense)(void);
typedef void     (*pfn_InvalidateLicense)(void);
typedef BOOL     (*pfn_IsLicenseValid)(void);

typedef uint16_t (*pfn_GetSlaveConfigAddr)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveAliasAddr)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveVendorId)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveProductCode)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveRevision)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveSerialNumber)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveOutputBits)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveOutputBytes)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveOutputOffset)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveInputBits)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveInputBytes)(uint16_t, uint16_t);
typedef uint32_t (*pfn_GetSlaveInputOffset)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveMailboxProto)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveMailboxWriteLength)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveMailboxWriteOffset)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveMailboxReadLength)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveMailboxReadOffset)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveHasDC)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveDCActive)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCCycle0)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCCycle1)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCShift)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveDCNext)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveDCPrevious)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCReceiveTimeA)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCReceiveTimeB)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCReceiveTimeC)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCReceiveTimeD)(uint16_t, uint16_t);

typedef uint8_t  (*pfn_GetSlavePhysicalType)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveBlockLRW)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveEep8Byte)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveEepPDI)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveCoEDetails)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveFoEDetails)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveEoEDetails)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveSoEDetails)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveIsLost)(uint16_t, uint16_t);
typedef int16_t  (*pfn_GetSlaveEbusCurrent)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveTopologyType)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveEntryPort)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveParentPort)(uint16_t, uint16_t);
typedef int      (*pfn_GetSlaveName)(uint16_t, uint16_t, char*, int);
typedef int      (*pfn_GetSlaveDeviceName)(uint16_t, uint16_t, char*, int);

typedef uint8_t  (*pfn_GetSlaveOutputStartBit)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveInputStartBit)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveFMMU0Function)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveFMMU1Function)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveFMMU2Function)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveFMMU3Function)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveMbxCount)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlavePDelay)(uint16_t, uint16_t);
typedef int32_t  (*pfn_GetSlaveDCParentPort)(uint16_t, uint16_t);
typedef uint8_t  (*pfn_GetSlaveConsumedPorts)(uint16_t, uint16_t);

typedef uint16_t (*pfn_GetSlaveParentStation)(uint16_t, uint16_t);

typedef BOOL     (*pfn_GetSlaveHasEsi)(uint16_t, uint16_t);
typedef BOOL     (*pfn_SetSlaveEsiFile)(uint16_t, uint16_t, const char*);
typedef BOOL     (*pfn_GetSlaveEsiVersion)(uint16_t, uint16_t, char*, int);
typedef BOOL     (*pfn_GetSlaveHasMDP)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveVendorName)(uint16_t, uint16_t, char*, int);

typedef BOOL     (*pfn_GetSlaveRedundancyActivated)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlavePrimaryLinkBroken)(uint16_t, uint16_t);
typedef BOOL     (*pfn_GetSlaveSecondaryLinkBroken)(uint16_t, uint16_t);

typedef void     (*pfn_DebugSlaveHasDC)(uint16_t, uint16_t);

typedef BOOL     (*pfn_FSoEInitConnection)(uint16_t, uint16_t, fsoe_config_t*);
typedef BOOL     (*pfn_FSoECloseConnection)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FSoEGetStatus)(uint16_t, uint16_t, fsoe_status_t*);
typedef BOOL     (*pfn_FSoERequestState)(uint16_t, uint16_t, int);
typedef int      (*pfn_FSoEGetState)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FSoEReset)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FSoEWriteSafeOutput)(uint16_t, uint16_t, const uint8_t*, uint32_t);
typedef BOOL     (*pfn_FSoEReadSafeInput)(uint16_t, uint16_t, uint8_t*, uint32_t*);
typedef BOOL     (*pfn_FSoEDownloadParameters)(uint16_t, uint16_t, const uint8_t*, uint32_t, uint32_t*);
typedef BOOL     (*pfn_FSoESetFailsafeOutput)(uint16_t, uint16_t, const uint8_t*, uint32_t);
typedef BOOL     (*pfn_FSoECheckWatchdog)(uint16_t, uint16_t);
typedef int      (*pfn_FSoEGetLastError)(uint16_t, uint16_t);
typedef void     (*pfn_FSoEClearError)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FSoEIsSlaveCapable)(uint16_t, uint16_t);
typedef uint16_t (*pfn_FSoEGetConnectionCount)(uint16_t);
typedef void     (*pfn_FSoEProcessCycle)(uint16_t);

typedef int      (*pfn_HotConnectAddGroup)(uint16_t, uint16_t, uint16_t, uint32_t, uint32_t);
typedef int      (*pfn_HotConnectRemoveGroup)(uint16_t, uint16_t);
typedef int      (*pfn_HotConnectGetGroupStatus)(uint16_t, uint16_t);
typedef int      (*pfn_HotConnectEnumerate)(uint16_t, void* , int);
typedef void     (*pfn_HotConnectClearAll)(uint16_t);
typedef int      (*pfn_HotConnectGetGroupCount)(uint16_t);

typedef BOOL     (*pfn_EOESendFrameEx)(uint16_t, uint16_t, uint8_t, const uint8_t*, int,
                                        uint8_t , uint32_t , int);
typedef BOOL     (*pfn_EOESetReceiveHook)(uint16_t, eoe_frame_cb_t);
typedef BOOL     (*pfn_EOEClearReceiveHook)(uint16_t);

typedef BOOL     (*pfn_VOEStartNotificationListener)(uint16_t);
typedef BOOL     (*pfn_VOEStopNotificationListener)(void);
typedef BOOL     (*pfn_VOEIsNotificationListening)(void);
typedef int      (*pfn_VOERegisterNotification)(uint16_t , uint32_t ,
                                                 uint16_t ,
                                                 voe_notification_callback_t, void*);
typedef BOOL     (*pfn_VOEUnregisterNotification)(int );

typedef int64_t  (*pfn_GetMasterDCTime)(uint16_t);
typedef uint16_t (*pfn_GetReferenceClockSlave)(uint16_t);

typedef BOOL     (*pfn_FSoEValidateConnId)(uint16_t );

typedef BOOL     (*pfn_FOERequestCancel)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FOEClearCancel)(uint16_t, uint16_t);
typedef BOOL     (*pfn_FOESetBusyHook)(uint16_t, foe_busy_callback_ffi_t);

typedef BOOL     (*pfn_DxSafeMdpInitConnection)(uint16_t, uint16_t, uint16_t, fsoe_mdp_config_t*);
typedef BOOL     (*pfn_DxSafeMdpCloseConnection)(uint16_t, uint16_t, uint16_t);
typedef BOOL     (*pfn_DxSafeMdpGetStatus)(uint16_t, uint16_t, uint16_t, fsoe_status_t*);
typedef BOOL     (*pfn_DxSafeMdpRequestState)(uint16_t, uint16_t, uint16_t, int);
typedef int      (*pfn_DxSafeMdpGetState)(uint16_t, uint16_t, uint16_t);
typedef BOOL     (*pfn_DxSafeMdpReset)(uint16_t, uint16_t, uint16_t);
typedef BOOL     (*pfn_DxSafeMdpWriteSafeOutput)(uint16_t, uint16_t, uint16_t, const uint8_t*, uint32_t);
typedef BOOL     (*pfn_DxSafeMdpReadSafeInput)(uint16_t, uint16_t, uint16_t, uint8_t*, uint32_t*);
typedef BOOL     (*pfn_DxSafeMdpDownloadParameters)(uint16_t, uint16_t, uint16_t, const uint8_t*, uint32_t, uint32_t*);
typedef BOOL     (*pfn_DxSafeMdpSetFailsafeOutput)(uint16_t, uint16_t, uint16_t, const uint8_t*, uint32_t);
typedef BOOL     (*pfn_DxSafeMdpCheckWatchdog)(uint16_t, uint16_t, uint16_t);
typedef int      (*pfn_DxSafeMdpGetLastError)(uint16_t, uint16_t, uint16_t);
typedef void     (*pfn_DxSafeMdpClearError)(uint16_t, uint16_t, uint16_t);
typedef uint16_t (*pfn_DxSafeMdpGetSlaveConnectionCount)(uint16_t, uint16_t);
typedef uint16_t (*pfn_DxSafeMdpDetectConnections)(uint16_t, uint16_t);
typedef BOOL     (*pfn_DxSafeMdpGetDeviceAddress)(uint16_t, uint16_t, uint16_t*);
typedef BOOL     (*pfn_DxSafeMdpGetModuleCommParam)(uint16_t, uint16_t, uint16_t, uint8_t*, uint32_t*);
typedef BOOL     (*pfn_DxSafeMdpGetModuleDiagnosis)(uint16_t, uint16_t, uint16_t, uint16_t*, uint16_t*);

typedef uint16_t (*pfn_CiA402_GetTransitionCommand)(int current, int target);
typedef BOOL     (*pfn_CiA402_RequestTransition)(uint16_t, uint16_t, int);
typedef BOOL     (*pfn_CiA402_FaultResetStep)(uint16_t, uint16_t, int);
typedef uint32_t (*pfn_CiA402_GetSupportedDriveModes)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_IsModeSupported)(uint16_t, uint16_t, int);
typedef int16_t  (*pfn_CiA402_GetQuickStopOption)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetQuickStopOption)(uint16_t, uint16_t, int16_t);
typedef int16_t  (*pfn_CiA402_GetShutdownOption)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetShutdownOption)(uint16_t, uint16_t, int16_t);
typedef int16_t  (*pfn_CiA402_GetDisableOperationOption)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetDisableOperationOption)(uint16_t, uint16_t, int16_t);
typedef int16_t  (*pfn_CiA402_GetHaltOption)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetHaltOption)(uint16_t, uint16_t, int16_t);
typedef int16_t  (*pfn_CiA402_GetFaultReactionOption)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetFaultReactionOption)(uint16_t, uint16_t, int16_t);
typedef uint16_t (*pfn_CiA402_GetErrorCode)(uint16_t, uint16_t);
typedef int      (*pfn_CiA402_GetErrorHistory)(uint16_t, uint16_t, uint32_t*, int);
typedef BOOL     (*pfn_CiA402_ClearErrorHistory)(uint16_t, uint16_t);
typedef BOOL     (*pfn_CiA402_SetHomingMethod)(uint16_t, uint16_t, int8_t);
typedef int8_t   (*pfn_CiA402_GetHomingMethod)(uint16_t, uint16_t);
typedef int      (*pfn_CiA402_GetSupportedHomingMethods)(uint16_t, uint16_t, int8_t*, int);
typedef BOOL     (*pfn_CiA402_IsStandardHomingMethod)(int8_t);

typedef int      (*pfn_EsmIsLegalTransition)(uint16_t from, uint16_t to);
typedef int      (*pfn_EsmGetLegalTransitions)(uint16_t from, uint8_t* out_states, int max_count);
typedef uint32_t (*pfn_EsmGetDefaultTimeoutMs)(uint16_t from, uint16_t to);
typedef int      (*pfn_EsmIsKnownAlStatusCode)(uint16_t al_status_code);
typedef int      (*pfn_EsmClassifyAlStatusCode)(uint16_t al_status_code);
typedef uint8_t  (*pfn_EsmGetMasterClass)(uint16_t master_index);

typedef BOOL     (*pfn_MBGStart)(uint16_t, uint16_t udp_port);
typedef BOOL     (*pfn_MBGStop)(uint16_t);
typedef BOOL     (*pfn_MBGIsRunning)(uint16_t);
typedef BOOL     (*pfn_MBGGetStats)(uint16_t, void* );
typedef void     (*pfn_MBGResetStats)(uint16_t);
typedef uint16_t (*pfn_MBGGetPort)(uint16_t);
typedef BOOL     (*pfn_MBGStartTcp)(uint16_t, uint16_t tcp_port);
typedef BOOL     (*pfn_MBGStopTcp)(uint16_t);
typedef BOOL     (*pfn_MBGTcpIsRunning)(uint16_t);
typedef uint16_t (*pfn_MBGGetTcpPort)(uint16_t);
typedef uint16_t (*pfn_MBGGetSelectedMaster)(uint16_t);
typedef BOOL     (*pfn_MBGSetSelectedMaster)(uint16_t, uint16_t selected);

typedef int      (*pfn_DiagnoseNicHealth)(uint16_t);
typedef int      (*pfn_VerifyNicHealth)(uint16_t, int num_probes, int timeout_ms);
typedef int      (*pfn_AutoRecoverNic)(uint16_t);

typedef int      (*pfn_coe_diag_poll_new_available)(uint16_t, uint16_t, uint32_t* out_abort_code);
typedef int      (*pfn_coe_diag_read_meta)(uint16_t, uint16_t, uint8_t* max_msgs, uint8_t* newest,
                                            uint8_t* acknowledged, uint16_t* flags16,
                                            uint32_t* out_abort_code);
typedef int      (*pfn_coe_diag_read_message)(uint16_t, uint16_t, uint8_t msg_subidx,
                                               uint8_t* out_buf, int buf_cap, int* out_len,
                                               uint32_t* out_abort_code);
typedef int      (*pfn_coe_diag_acknowledge)(uint16_t, uint16_t, uint8_t ack_subidx,
                                              uint32_t* out_abort_code);

typedef uint16_t (*pfn_GetGroupActualWKC)(uint16_t, uint8_t group);
typedef int      (*pfn_GetGroupDiag)(uint16_t, uint8_t group, uint16_t* consecutive_miss,
                                      uint32_t* total_frames, uint32_t* mismatch_frames);
typedef void     (*pfn_TraceLog)(const char* msg);
typedef uint16_t (*pfn_RecoverSlaveToOP)(uint16_t, uint16_t);
typedef uint16_t (*pfn_GetSlaveSMLength)(uint16_t, uint16_t, uint8_t sm_idx);
typedef int      (*pfn_MDPAutoEnumerate)(uint16_t);
typedef int      (*pfn_GetSlavePortLinkStatus)(uint16_t, uint8_t* out_port_link,
                                                uint8_t* out_unreachable, uint16_t max_slaves);
typedef BOOL     (*pfn_SetDcSyncMode)(uint16_t, uint16_t, uint8_t sync_type);
typedef uint8_t  (*pfn_GetDcSyncMode)(uint16_t, uint16_t);

typedef struct dll {
    DLL_HANDLE handle;

    pfn_Initialize              Initialize;
    pfn_InitializeSpecificMaster InitializeSpecificMaster;
    pfn_Dispose                 Dispose;
    pfn_Start                   Start;
    pfn_Stop                    Stop;
    pfn_GetMaxMasterInstances   GetMaxMasterInstances;

    pfn_SetNetwork              SetNetwork;
    pfn_SetState                SetState;
    pfn_SetStateWithTimeout     SetStateWithTimeout;
    pfn_SetSlaveStateWithTimeout SetSlaveStateWithTimeout;
    pfn_SetStateSequence        SetStateSequence;
    pfn_SetStateWithStartup     SetStateWithStartup;
    pfn_GetLinkStatus           GetLinkStatus;
    pfn_GetSlaveState           GetSlaveState;
    pfn_GetSlaveALStatusCode    GetSlaveALStatusCode;

    pfn_GetIO                   GetIO;
    pfn_LockIOmap               LockIOmap;
    pfn_UnlockIOmap             UnlockIOmap;
    pfn_WriteSlaveOutput        WriteSlaveOutput;
    pfn_WriteSlaveOutputByte    WriteSlaveOutputByte;
    pfn_SetMutexProtection      SetMutexProtection;
    pfn_GetMutexProtection      GetMutexProtection;

    pfn_SDOwrite                dx_sdo_write;
    pfn_SDOread                 dx_sdo_read;
    pfn_SDOread_ex              dx_sdo_read_ex;
    pfn_SDOwrite_ex             dx_sdo_write_ex;
    pfn_GetSlaveSDOList         GetSlaveSDOList;
    pfn_GetSlaveSDOListBasic    GetSlaveSDOListBasic;
    pfn_GetSlavePointer_SDO     GetSlavePointer_SDO;
    pfn_GetSlavePointer_SDO_WithODList GetSlavePointer_SDO_WithODList;
    pfn_GetSlavePointer_SDO_Value GetSlavePointer_SDO_Value;
    pfn_GetSlavePointer_SDO_IndexValue GetSlavePointer_SDO_IndexValue;
    pfn_GetMultiSlaveSDOList    GetMultiSlaveSDOList;
    pfn_FreeMultiSlaveSDOList   FreeMultiSlaveSDOList;
    pfn_SDOReadMultiple         SDOReadMultiple;

    pfn_coe_get_od_list         coe_get_od_list;
    pfn_coe_get_object_desc     coe_get_object_desc;
    pfn_coe_get_entry_desc      coe_get_entry_desc;
    pfn_coe_free_odlist         coe_free_odlist;
    pfn_coe_free_oelist         coe_free_oelist;

    pfn_AddStartupParameter     AddStartupParameter;
    pfn_AddStartupParameterBatch AddStartupParameterBatch;
    pfn_ClearStartupParameters  ClearStartupParameters;
    pfn_GetStartupParameterCount GetStartupParameterCount;
    pfn_ApplyStartupParameters  ApplyStartupParameters;
    pfn_ApplyStartupParametersAll ApplyStartupParametersAll;

    pfn_LoadConfigJson          LoadConfigJson;
    pfn_AutoConfigureSM         AutoConfigureSM;
    pfn_EcInit                  EcInit;
    pfn_EcInitFromFile          EcInitFromFile;
    pfn_EcClose                 EcClose;

    pfn_SetMasterDCCycleTime    SetMasterDCCycleTime;
    pfn_SetMasterLoopCycleTime  SetMasterLoopCycleTime;
    pfn_SetSyncBySlaveIndex     SetSyncBySlaveIndex;
    pfn_ConfigureDCAll          ConfigureDCAll;
    pfn_UpdatePropagationDelays UpdatePropagationDelays;
    pfn_AutoCalculateDCShift    AutoCalculateDCShift;
    pfn_EnableContinuousMeasurement EnableContinuousMeasurement;
    pfn_EnableDriftCompensation EnableDriftCompensation;
    pfn_SetDCAutoShiftEnabled   SetDCAutoShiftEnabled;
    pfn_GetDCAutoShiftEnabled   GetDCAutoShiftEnabled;
    pfn_GetSlavePropagationDelay GetSlavePropagationDelay;
    pfn_GetMaxPropagationDelay  GetMaxPropagationDelay;
    pfn_GetSlaveSyncWindowStatus GetSlaveSyncWindowStatus;
    pfn_SetSyncWindowThreshold  SetSyncWindowThreshold;
    pfn_GetSyncWindowThreshold  GetSyncWindowThreshold;
    pfn_ResetSlaveSyncWindowStats ResetSlaveSyncWindowStats;
    pfn_GetMaxSyncDifference    GetMaxSyncDifference;
    pfn_IsAllSlavesInSync       IsAllSlavesInSync;

    pfn_SetSlaveGroup           SetSlaveGroup;
    pfn_GetSlaveGroup           GetSlaveGroup;
    pfn_SetGroupCycleDivider    SetGroupCycleDivider;
    pfn_GetGroupCycleDivider    GetGroupCycleDivider;
    pfn_SetGroupEnabled         SetGroupEnabled;
    pfn_GetGroupEnabled         GetGroupEnabled;
    pfn_GetGroupExpectedWKC     GetGroupExpectedWKC;
    pfn_GetActiveGroupCount     GetActiveGroupCount;
    pfn_GetGroupSlaveCount      GetGroupSlaveCount;

    pfn_SoERead                 dx_soe_read;
    pfn_SoEWrite                dx_soe_write;
    pfn_SoEReadAttributes       dx_soe_read_attributes;
    pfn_SoEReadName             dx_soe_read_name;
    pfn_SoEReadUnit             dx_soe_read_unit;
    pfn_SoEReadIDNList          dx_soe_read_idn_list;
    pfn_SoEReadMinMax           dx_soe_read_min_max;

    pfn_FOERead                 dx_foe_read;
    pfn_FOEWrite                dx_foe_write;
    pfn_FOEReadEx               dx_foe_read_ex;
    pfn_FOEWriteEx              dx_foe_write_ex;
    pfn_FOESetProgressHook      dx_foe_set_progress_hook;
    pfn_FOEClearProgressHook    dx_foe_clear_progress_hook;

    pfn_EOESetIP                dx_eoe_set_ip;
    pfn_EOEGetIP                dx_eoe_get_ip;
    pfn_EOESendFrame            dx_eoe_send_frame;
    pfn_EOEReceiveFrame         dx_eoe_receive_frame;
    pfn_EOESetMAC               dx_eoe_set_mac;
    pfn_EOEGetMAC               dx_eoe_get_mac;
    pfn_EOESetDNS               dx_eoe_set_dns;
    pfn_EOEGetDNS               dx_eoe_get_dns;
    pfn_EOEGetFullParam         dx_eoe_get_full_param;
    pfn_EOESetFullParam         dx_eoe_set_full_param;
    pfn_EOESetAddressFilter     dx_eoe_set_address_filter;
    pfn_EOEGetAddressFilter     dx_eoe_get_address_filter;

    pfn_AOESendCommand          dx_aoe_send_command;
    pfn_AOEReadWrite            dx_aoe_read_write;
    pfn_AOEReadDeviceInfo       dx_aoe_read_device_info;
    pfn_AOEReadState            dx_aoe_read_state;
    pfn_AOEWriteControl         dx_aoe_write_control;
    pfn_AOEAddNotification      dx_aoe_add_notification;
    pfn_AOEDelNotification      dx_aoe_del_notification;
    pfn_AOESetConfig            dx_aoe_set_config;
    pfn_AOEGetConfig            dx_aoe_get_config;
    pfn_AOEStartNotificationListener dx_aoe_start_notification_listener;
    pfn_AOEStopNotificationListener  dx_aoe_stop_notification_listener;
    pfn_AOEIsNotificationListening   dx_aoe_is_notification_listening;
    pfn_AOERegisterNotification      dx_aoe_register_notification;
    pfn_AOEUnregisterNotification    dx_aoe_unregister_notification;

    pfn_VOESend                 dx_voe_send;
    pfn_VOEReceive              dx_voe_receive;
    pfn_VOESendRaw              dx_voe_send_raw;
    pfn_VOEReceiveRaw           dx_voe_receive_raw;
    pfn_VOEIsSupported          dx_voe_is_supported;

    pfn_SetLogCallback          SetLogCallback;
    pfn_SetCrashCallback        SetCrashCallback;
    pfn_RegisterProcessDataCyclicCallbackSync  RegisterPDOCyclicSync;

    pfn_RegisterSlaveStateChangeCallbackSync   RegisterStateChangeSync;
    pfn_RegisterSlaveStateChangeCallbackAsync  RegisterStateChangeAsync;
    pfn_RegisterEmergencyEventCallback         RegisterEmergency;
    pfn_RegisterSlaveDiscoveryCallbackSync     RegisterDiscoverySync;
    pfn_RegisterSlaveDiscoveryCallbackAsync    RegisterDiscoveryAsync;
    pfn_RegisterPDOFrameLossCallback           RegisterPDOFrameLoss;
    pfn_RegisterRedundancyModeChangedCallback  RegisterRedundancyChanged;
    pfn_RegisterSlavePreOpReconfigCallback     RegisterPreOpReconfig;

    pfn_SetDCSyncLostCallback   SetDCSyncLostCallback;
    pfn_RegisterSlaveIdentityMismatchCallback  RegisterSlaveIdentityMismatch;
    pfn_RegisterSlavePortLinkChangedCallback   RegisterSlavePortLinkChanged;
    pfn_AcknowledgeSlaveReplacement            AcknowledgeSlaveReplacement;
    pfn_WriteSlaveDLPORT        WriteSlaveDLPORT;
    pfn_ReadSlaveDLPORT         ReadSlaveDLPORT;
    pfn_ClearAllEvents          ClearAllEvents;

    pfn_GetMasterState          GetMasterState;
    pfn_GetMasterStateCache     GetMasterStateCache;
    pfn_GetSlave                GetSlave;
    pfn_GetSlaveDetailedInfo    GetSlaveDetailedInfo;
    pfn_GetCommunicationStats   GetCommunicationStats;
    pfn_ResetCommunicationStats ResetCommunicationStats;
    pfn_GetDetailedDiagnostics  GetDetailedDiagnostics;
    pfn_ResetDiagnostics        ResetDiagnostics;
    pfn_GetDiagnosticsPointer   GetDiagnosticsPointer;
    pfn_GetSummaryPointer       GetSummaryPointer;
    pfn_SetDiagnosticsEnabled   SetDiagnosticsEnabled;
    pfn_GetDiagnosticsEnabled   GetDiagnosticsEnabled;
    pfn_GetExpectedWKC          GetExpectedWKC;
    pfn_SetExpectedWKC          SetExpectedWKC;

    pfn_GetPacketLossRate       GetPacketLossRate;
    pfn_GetLateFrameRate        GetLateFrameRate;
    pfn_GetWdkPrimaryFrameTx    GetWdkPrimaryFrameTx;
    pfn_GetWdkPrimaryFrameRx    GetWdkPrimaryFrameRx;
    pfn_GetWdkSecondaryFrameTx  GetWdkSecondaryFrameTx;
    pfn_GetWdkSecondaryFrameRx  GetWdkSecondaryFrameRx;
    pfn_GetWdkPdoIdxDropCount   GetWdkPdoIdxDropCount;
    pfn_GetSlaveLinkQuality     GetSlaveLinkQuality;

    pfn_RecordPDOCycleStart     RecordPDOCycleStart;
    pfn_RecordWKC               RecordWKC;
    pfn_UpdateDiagnosticsSnapshot UpdateDiagnosticsSnapshot;
    pfn_ResetSlavePortErrorCounters ResetSlavePortErrorCounters;
    pfn_GetDllVersionInfo       GetDllVersionInfo;
    pfn_DumpSlaveStructOffsets  DumpSlaveStructOffsets;

    pfn_GetMasterIdentity       GetMasterIdentity;
    pfn_GetMasterDiagData       GetMasterDiagData;
    pfn_ec_validate_config      ec_validate_config;
    pfn_ec_perf_export_csv      ec_perf_export_csv;
    pfn_GetBreakPoints          GetBreakPoints;
    pfn_GetRingMode             GetRingMode;
    pfn_GetSecondaryLinkStatus  GetSecondaryLinkStatus;
    pfn_ReadSlavePortErrorCounters ReadSlavePortErrorCounters;
    pfn_ReadAllSlavePortErrorCounters ReadAllSlavePortErrorCounters;
    pfn_GetSlavePortErrorStats  GetSlavePortErrorStats;
    pfn_UpdateDiagnosticsWithESCErrors UpdateDiagnosticsWithESCErrors;
    pfn_GetDiagnosticsSnapshot  GetDiagnosticsSnapshot;

    pfn_GetSlaveWcState         GetSlaveWcState;
    pfn_GetSlaveAlStatusMirror  GetSlaveAlStatusMirror;
    pfn_GetWcDeficit            GetWcDeficit;
    pfn_GetWcStateSeq           GetWcStateSeq;
    pfn_GetMappedSlaveCount     GetMappedSlaveCount;
    pfn_GetWkcActualMirror      GetWkcActualMirror;
    pfn_GetWkcExpectedMirror    GetWkcExpectedMirror;

    pfn_GetNetworkInfo          GetNetworkInfo;
    pfn_GetNetworksPointer      GetNetworksPointer;
    pfn_QuickSlaveCount         QuickSlaveCount;
    pfn_QuickFindRedundantPairBatch QuickFindRedundantPairBatch;

    pfn_ReadSlaveInfo           ReadSlaveInfo;
    pfn_GetScannedSlaveCount    GetScannedSlaveCount;
    pfn_GetScannedSlaveInfo     GetScannedSlaveInfo;
    pfn_GetRingSlaveCount       GetRingSlaveCount;

    pfn_GetAvailableCpuCores    GetAvailableCpuCores;
    pfn_SetMasterCpuAffinity    SetMasterCpuAffinity;
    pfn_SetProcessCpuAffinity   SetProcessCpuAffinity;
    pfn_SetPDOThreadCpuAffinity SetPDOThreadCpuAffinity;
    pfn_GetPDOThreadCpuAffinity GetPDOThreadCpuAffinity;
    pfn_ApplyRealtimeOptimizations ApplyRealtimeOptimizations;
    pfn_RemoveRealtimeOptimizations RemoveRealtimeOptimizations;
    pfn_GetRealtimeOptimizationsStatus GetRealtimeOptimizationsStatus;
    pfn_GetTimingMode           GetTimingMode;
    pfn_DarraValidateTimerAccuracy DarraValidateTimerAccuracy;

    pfn_SetRedProcessdata       SetRedProcessdata;
    pfn_GetRedProcessdata       GetRedProcessdata;
    pfn_EnableRedundancy        EnableRedundancy;
    pfn_GetRedundancyStatus     GetRedundancyStatus;
    pfn_ForceRedundancyFailover ForceRedundancyFailover;
    pfn_CheckRedundancyHealth   CheckRedundancyHealth;

    pfn_WriteSlaveRegister      WriteSlaveRegister;
    pfn_ReadSlaveRegister       ReadSlaveRegister;
    pfn_ConfigureSyncManager    ConfigureSyncManager;
    pfn_ConfigureFMMU           ConfigureFMMU;
    pfn_EnableOutputSyncManager EnableOutputSyncManager;
    pfn_DisableOutputSyncManager DisableOutputSyncManager;
    pfn_GetSlaveOpOnlyFlag      GetSlaveOpOnlyFlag;
    pfn_SetSlaveErrorAck        SetSlaveErrorAck;
    pfn_GetSlaveDeviceEmulationFlag GetSlaveDeviceEmulationFlag;

    pfn_SIIReadWord             SIIReadWord;
    pfn_SIIWriteWord            SIIWriteWord;

    pfn_SetSlaveWatchdog        SetSlaveWatchdog;
    pfn_SetSlavePdiWatchdog     SetSlavePdiWatchdog;
    pfn_GetSlaveWatchdogConfig  GetSlaveWatchdogConfig;
    pfn_GetSlaveWatchdogStatus  GetSlaveWatchdogStatus;
    pfn_SetAllSlaveWatchdog     SetAllSlaveWatchdog;
    pfn_SetAllSlavePdiWatchdog  SetAllSlavePdiWatchdog;

    pfn_GetSlaveIdentity        GetSlaveIdentity;
    pfn_VerifySlaveIdentity     VerifySlaveIdentity;
    pfn_VerifyAllSlaveIdentities VerifyAllSlaveIdentities;
    pfn_SetSlaveOptional        SetSlaveOptional;
    pfn_GetSlaveOptional        GetSlaveOptional;
    pfn_SetSlaveSupportsFrameRepeat SetSlaveSupportsFrameRepeat;
    pfn_GetSlaveSupportsFrameRepeat GetSlaveSupportsFrameRepeat;
    pfn_GetSlaveNeedsStartupReconfig GetSlaveNeedsStartupReconfig;
    pfn_ClearSlaveNeedsStartupReconfig ClearSlaveNeedsStartupReconfig;

    pfn_GetSlaveEsmTimeouts     GetSlaveEsmTimeouts;
    pfn_SetSlaveEsmTimeouts     SetSlaveEsmTimeouts;

    pfn_SetPDOLogging           SetPDOLogging;
    pfn_SetMailboxLogging       SetMailboxLogging;
    pfn_SetDebugLogging         SetDebugLogging;
    pfn_CloseDebugLog           CloseDebugLog;

    pfn_GetPrimaryWKC           GetPrimaryWKC;
    pfn_GetSecondaryWKC         GetSecondaryWKC;
    pfn_GetPrimaryWKCEx         GetPrimaryWKCEx;
    pfn_GetSecondaryWKCEx       GetSecondaryWKCEx;

    pfn_FreeMemory              FreeMemory;

    pfn_IsWdkAvailable          IsWdkAvailable;
    pfn_SetWdkMode              SetWdkMode;
    pfn_GetWdkMode              GetWdkMode;
    pfn_StartWdkRT              StartWdkRT;
    pfn_StopWdkRT               StopWdkRT;

    pfn_SetWdkPdOffload         SetWdkPdOffload;
    pfn_PiggybackRequest        PiggybackRequest;
    pfn_PiggybackResponse       PiggybackResponse;

    pfn_GetSlaveStateLive          GetSlaveStateLive;
    pfn_GetSlaveALStatusCodeLive   GetSlaveALStatusCodeLive;

    pfn_SetLicenseExpiredCallback   SetLicenseExpiredCallback;
    pfn_UnsetLicenseExpiredCallback UnsetLicenseExpiredCallback;

    pfn_SetUdpMode              SetUdpMode;
    pfn_GetUdpMode              GetUdpMode;
    pfn_IsUdpAvailable          IsUdpAvailable;

    pfn_AbortScan               AbortScan;
    pfn_ResetScanAbort          ResetScanAbort;
    pfn_AbortNetwork            AbortNetwork;
    pfn_ResetAbortNetwork       ResetAbortNetwork;
    pfn_EmergencyCloseNics      EmergencyCloseNics;

    pfn_CiA402_ParseState       CiA402_ParseState;
    pfn_CiA402_GetEnableCommand CiA402_GetEnableCommand;
    pfn_CiA402_SetMode          CiA402_SetMode;
    pfn_CiA402_GetMode          CiA402_GetMode;
    pfn_CiA402_ReadStatusWord   CiA402_ReadStatusWord;
    pfn_CiA402_WriteControlWord CiA402_WriteControlWord;
    pfn_CiA402_Enable           CiA402_Enable;
    pfn_CiA402_FaultReset       CiA402_FaultReset;

    pfn_EmcyGetHistory          EmcyGetHistory;
    pfn_EmcyClearHistory        EmcyClearHistory;
    pfn_EmcyGetCount            EmcyGetCount;

    pfn_PdoWriteInt8            PdoWriteInt8;
    pfn_PdoWriteInt16           PdoWriteInt16;
    pfn_PdoWriteInt32           PdoWriteInt32;
    pfn_PdoWriteUint8           PdoWriteUint8;
    pfn_PdoWriteUint16          PdoWriteUint16;
    pfn_PdoWriteUint32          PdoWriteUint32;
    pfn_PdoReadInt8             PdoReadInt8;
    pfn_PdoReadInt16            PdoReadInt16;
    pfn_PdoReadInt32            PdoReadInt32;
    pfn_PdoReadUint8            PdoReadUint8;
    pfn_PdoReadUint16           PdoReadUint16;
    pfn_PdoReadUint32           PdoReadUint32;

    pfn_PDOReadInputU8          PDOReadInputU8;
    pfn_PDOReadInputI16         PDOReadInputI16;
    pfn_PDOReadInputU16         PDOReadInputU16;
    pfn_PDOReadInputI32         PDOReadInputI32;
    pfn_PDOReadInputU32         PDOReadInputU32;
    pfn_PDOReadInputF32         PDOReadInputF32;
    pfn_PDOWriteOutputU8        PDOWriteOutputU8;
    pfn_PDOWriteOutputI16       PDOWriteOutputI16;
    pfn_PDOWriteOutputU16       PDOWriteOutputU16;
    pfn_PDOWriteOutputI32       PDOWriteOutputI32;
    pfn_PDOWriteOutputU32       PDOWriteOutputU32;
    pfn_PDOWriteOutputF32       PDOWriteOutputF32;

    pfn_PDOReadDirect           PDOReadDirect;
    pfn_PDOWriteDirect          PDOWriteDirect;
    pfn_PDOBatchRead            PDOBatchRead;
    pfn_PDOBatchWrite           PDOBatchWrite;
    pfn_GetPDOStats             GetPDOStats;
    pfn_ResetPDOStats           ResetPDOStats;
    pfn_EnablePDOMonitoring     EnablePDOMonitoring;
    pfn_IsPDOMonitoringEnabled  IsPDOMonitoringEnabled;

    pfn_GetPDOMapping           GetPDOMapping;
    pfn_GetPDOFrameLossStats    GetPDOFrameLossStats;
    pfn_ResetPDOFrameLossStats  ResetPDOFrameLossStats;

    pfn_mbx_get_stats_by_master    mbx_get_stats_by_master;
    pfn_mbx_reset_stats_by_master  mbx_reset_stats_by_master;
    pfn_mbx_submit_async_by_master mbx_submit_async_by_master;
    pfn_mbx_wait_by_master         mbx_wait_by_master;
    pfn_mbx_cancel_by_master       mbx_cancel_by_master;
    pfn_mbx_get_result_by_master   mbx_get_result_by_master;

    pfn_GetTopology             GetTopology;
    pfn_TopologyBuild           TopologyBuild;
    pfn_TopologyGetChildren     TopologyGetChildren;
    pfn_TopologyGetRoots        TopologyGetRoots;
    pfn_GetSlaveActivePorts     GetSlaveActivePorts;
    pfn_GetSlaveParent          GetSlaveParent;

    pfn_GetSerialNumber         GetSerialNumber;
    pfn_GetDeviceName           GetDeviceName;
    pfn_GetUserEmail            GetUserEmail;
    pfn_GetWindowsProductKey    GetWindowsProductKey;
    pfn_GetDriverList           GetDriverList;
    pfn_VerifyLicense           VerifyLicense;
    pfn_InvalidateLicense       InvalidateLicense;
    pfn_IsLicenseValid          IsLicenseValid;

    pfn_GetSlaveConfigAddr      GetSlaveConfigAddr;
    pfn_GetSlaveAliasAddr       GetSlaveAliasAddr;
    pfn_GetSlaveVendorId        GetSlaveVendorId;
    pfn_GetSlaveProductCode     GetSlaveProductCode;
    pfn_GetSlaveRevision        GetSlaveRevision;
    pfn_GetSlaveSerialNumber    GetSlaveSerialNumber;
    pfn_GetSlaveOutputBits      GetSlaveOutputBits;
    pfn_GetSlaveOutputBytes     GetSlaveOutputBytes;
    pfn_GetSlaveOutputOffset    GetSlaveOutputOffset;
    pfn_GetSlaveInputBits       GetSlaveInputBits;
    pfn_GetSlaveInputBytes      GetSlaveInputBytes;
    pfn_GetSlaveInputOffset     GetSlaveInputOffset;
    pfn_GetSlaveMailboxProto    GetSlaveMailboxProto;
    pfn_GetSlaveMailboxWriteLength GetSlaveMailboxWriteLength;
    pfn_GetSlaveMailboxWriteOffset GetSlaveMailboxWriteOffset;
    pfn_GetSlaveMailboxReadLength  GetSlaveMailboxReadLength;
    pfn_GetSlaveMailboxReadOffset  GetSlaveMailboxReadOffset;
    pfn_GetSlaveHasDC           GetSlaveHasDC;
    pfn_GetSlaveDCActive        GetSlaveDCActive;
    pfn_GetSlaveDCCycle0        GetSlaveDCCycle0;
    pfn_GetSlaveDCCycle1        GetSlaveDCCycle1;
    pfn_GetSlaveDCShift         GetSlaveDCShift;
    pfn_GetSlaveDCNext          GetSlaveDCNext;
    pfn_GetSlaveDCPrevious      GetSlaveDCPrevious;
    pfn_GetSlaveDCReceiveTimeA  GetSlaveDCReceiveTimeA;
    pfn_GetSlaveDCReceiveTimeB  GetSlaveDCReceiveTimeB;
    pfn_GetSlaveDCReceiveTimeC  GetSlaveDCReceiveTimeC;
    pfn_GetSlaveDCReceiveTimeD  GetSlaveDCReceiveTimeD;

    pfn_GetSlavePhysicalType    GetSlavePhysicalType;
    pfn_GetSlaveBlockLRW        GetSlaveBlockLRW;
    pfn_GetSlaveEep8Byte        GetSlaveEep8Byte;
    pfn_GetSlaveEepPDI          GetSlaveEepPDI;
    pfn_GetSlaveCoEDetails      GetSlaveCoEDetails;
    pfn_GetSlaveFoEDetails      GetSlaveFoEDetails;
    pfn_GetSlaveEoEDetails      GetSlaveEoEDetails;
    pfn_GetSlaveSoEDetails      GetSlaveSoEDetails;
    pfn_GetSlaveIsLost          GetSlaveIsLost;
    pfn_GetSlaveEbusCurrent     GetSlaveEbusCurrent;
    pfn_GetSlaveTopologyType    GetSlaveTopologyType;
    pfn_GetSlaveEntryPort       GetSlaveEntryPort;
    pfn_GetSlaveParentPort      GetSlaveParentPort;
    pfn_GetSlaveName            GetSlaveName;
    pfn_GetSlaveDeviceName      GetSlaveDeviceName;

    pfn_GetSlaveOutputStartBit  GetSlaveOutputStartBit;
    pfn_GetSlaveInputStartBit   GetSlaveInputStartBit;
    pfn_GetSlaveFMMU0Function   GetSlaveFMMU0Function;
    pfn_GetSlaveFMMU1Function   GetSlaveFMMU1Function;
    pfn_GetSlaveFMMU2Function   GetSlaveFMMU2Function;
    pfn_GetSlaveFMMU3Function   GetSlaveFMMU3Function;
    pfn_GetSlaveMbxCount        GetSlaveMbxCount;
    pfn_GetSlavePDelay          GetSlavePDelay;
    pfn_GetSlaveDCParentPort    GetSlaveDCParentPort;
    pfn_GetSlaveConsumedPorts   GetSlaveConsumedPorts;

    pfn_GetSlaveParentStation   GetSlaveParentStation;

    pfn_GetSlaveHasEsi          GetSlaveHasEsi;
    pfn_SetSlaveEsiFile         SetSlaveEsiFile;
    pfn_GetSlaveEsiVersion      GetSlaveEsiVersion;
    pfn_GetSlaveHasMDP          GetSlaveHasMDP;
    pfn_GetSlaveVendorName      GetSlaveVendorName;

    pfn_GetSlaveRedundancyActivated GetSlaveRedundancyActivated;
    pfn_GetSlavePrimaryLinkBroken   GetSlavePrimaryLinkBroken;
    pfn_GetSlaveSecondaryLinkBroken GetSlaveSecondaryLinkBroken;

    pfn_DebugSlaveHasDC         DebugSlaveHasDC;

    pfn_FSoEInitConnection      dx_fsoe_init_connection;
    pfn_FSoECloseConnection     dx_fsoe_close_connection;
    pfn_FSoEGetStatus           dx_fsoe_get_status;
    pfn_FSoERequestState        dx_fsoe_request_state;
    pfn_FSoEGetState            dx_fsoe_get_state;
    pfn_FSoEReset               dx_fsoe_reset;
    pfn_FSoEWriteSafeOutput     dx_fsoe_write_safe_output;
    pfn_FSoEReadSafeInput       dx_fsoe_read_safe_input;
    pfn_FSoEDownloadParameters  dx_fsoe_download_parameters;
    pfn_FSoESetFailsafeOutput   dx_fsoe_set_failsafe_output;
    pfn_FSoECheckWatchdog       dx_fsoe_check_watchdog;
    pfn_FSoEGetLastError        dx_fsoe_get_last_error;
    pfn_FSoEClearError          dx_fsoe_clear_error;
    pfn_FSoEIsSlaveCapable      dx_fsoe_is_slave_capable;
    pfn_FSoEGetConnectionCount  dx_fsoe_get_connection_count;
    pfn_FSoEProcessCycle        dx_fsoe_process_cycle;

    pfn_DxSafeMdpInitConnection   DxSafeMdpInitConnection;
    pfn_DxSafeMdpCloseConnection  DxSafeMdpCloseConnection;
    pfn_DxSafeMdpGetStatus        DxSafeMdpGetStatus;
    pfn_DxSafeMdpRequestState     DxSafeMdpRequestState;
    pfn_DxSafeMdpGetState         DxSafeMdpGetState;
    pfn_DxSafeMdpReset            DxSafeMdpReset;
    pfn_DxSafeMdpWriteSafeOutput  DxSafeMdpWriteSafeOutput;
    pfn_DxSafeMdpReadSafeInput    DxSafeMdpReadSafeInput;
    pfn_DxSafeMdpDownloadParameters DxSafeMdpDownloadParameters;
    pfn_DxSafeMdpSetFailsafeOutput  DxSafeMdpSetFailsafeOutput;
    pfn_DxSafeMdpCheckWatchdog    DxSafeMdpCheckWatchdog;
    pfn_DxSafeMdpGetLastError     DxSafeMdpGetLastError;
    pfn_DxSafeMdpClearError       DxSafeMdpClearError;
    pfn_DxSafeMdpGetSlaveConnectionCount DxSafeMdpGetSlaveConnectionCount;
    pfn_DxSafeMdpDetectConnections DxSafeMdpDetectConnections;
    pfn_DxSafeMdpGetDeviceAddress DxSafeMdpGetDeviceAddress;
    pfn_DxSafeMdpGetModuleCommParam DxSafeMdpGetModuleCommParam;
    pfn_DxSafeMdpGetModuleDiagnosis DxSafeMdpGetModuleDiagnosis;

    pfn_HotConnectAddGroup       HotConnectAddGroup;
    pfn_HotConnectRemoveGroup    HotConnectRemoveGroup;
    pfn_HotConnectGetGroupStatus HotConnectGetGroupStatus;
    pfn_HotConnectEnumerate      HotConnectEnumerate;
    pfn_HotConnectClearAll       HotConnectClearAll;
    pfn_HotConnectGetGroupCount  HotConnectGetGroupCount;

    pfn_EOESendFrameEx           dx_eoe_send_frame_ex;
    pfn_EOESetReceiveHook        dx_eoe_set_receive_hook;
    pfn_EOEClearReceiveHook      dx_eoe_clear_receive_hook;

    pfn_VOEStartNotificationListener dx_voe_start_notification_listener;
    pfn_VOEStopNotificationListener  dx_voe_stop_notification_listener;
    pfn_VOEIsNotificationListening   dx_voe_is_notification_listening;
    pfn_VOERegisterNotification      dx_voe_register_notification;
    pfn_VOEUnregisterNotification    dx_voe_unregister_notification;

    pfn_GetMasterDCTime          GetMasterDCTime;
    pfn_GetReferenceClockSlave   GetReferenceClockSlave;

    pfn_FSoEValidateConnId       dx_fsoe_validate_conn_id;

    pfn_FOERequestCancel         dx_foe_request_cancel;
    pfn_FOEClearCancel           dx_foe_clear_cancel;
    pfn_FOESetBusyHook           dx_foe_set_busy_hook;

    pfn_GetDriverVersion              GetDriverVersion;
    pfn_InvalidateDriverVersionCache  InvalidateDriverVersionCache;
    pfn_EnsureDriversRunning          EnsureDriversRunning;

    pfn_DarraEcat_KernelProbe         DarraEcat_KernelProbe;
    pfn_DarraEcat_KernelStatusMessage DarraEcat_KernelStatusMessage;
    pfn_DarraEcat_KernelInstallerUrl  DarraEcat_KernelInstallerUrl;

    pfn_GetCycleEventHandle           GetCycleEventHandle;
    pfn_GetCycleEventName             GetCycleEventName;
    pfn_WaitForCycleEvent             WaitForCycleEvent;
    pfn_GetCycleCount                 GetCycleCount;

    pfn_UnregisterProcessDataCyclicCallbackSync  UnregisterProcessDataCyclicCallbackSync;

    pfn_UnregisterSlaveStateChangeCallbackSync   UnregisterSlaveStateChangeCallbackSync;
    pfn_UnregisterSlaveStateChangeCallbackAsync  UnregisterSlaveStateChangeCallbackAsync;
    pfn_UnregisterEmergencyEventCallback         UnregisterEmergencyEventCallback;
    pfn_UnregisterSlaveDiscoveryCallbackSync     UnregisterSlaveDiscoveryCallbackSync;
    pfn_UnregisterSlaveDiscoveryCallbackAsync    UnregisterSlaveDiscoveryCallbackAsync;
    pfn_UnregisterPDOFrameLossCallback           UnregisterPDOFrameLossCallback;
    pfn_UnregisterRedundancyModeChangedCallback  UnregisterRedundancyModeChangedCallback;
    pfn_UnregisterSlavePreOpReconfigCallback     UnregisterSlavePreOpReconfigCallback;
    pfn_UnregisterSlaveIdentityMismatchCallback  UnregisterSlaveIdentityMismatchCallback;

    pfn_UnregisterSlavePortLinkChangedCallback   UnregisterSlavePortLinkChangedCallback;
    pfn_UnsetLogCallback                         UnsetLogCallback;
    pfn_UnsetCrashCallback                       UnsetCrashCallback;
    pfn_UnsetDCSyncLostCallback                  UnsetDCSyncLostCallback;

    pfn_AL_StatusCode_GetDescriptionChinese      AL_StatusCode_GetDescriptionChinese;
    pfn_AL_StatusCode_GetRecoveryHintChinese     AL_StatusCode_GetRecoveryHintChinese;

    pfn_GetMasterAlstatRefresh        GetMasterAlstatRefresh;
    pfn_GetPiggybackDiagCounters      GetPiggybackDiagCounters;
    pfn_GetPiggybackDiagCounters2     GetPiggybackDiagCounters2;
    pfn_GetTopoPriIntact              GetTopoPriIntact;
    pfn_GetTopoSecIntact              GetTopoSecIntact;

    pfn_HotSwapRebuild                HotSwapRebuild;

    pfn_GetSlaveFreeRunDemoted        GetSlaveFreeRunDemoted;
    pfn_GetSlaveMailboxHealth         GetSlaveMailboxHealth;
    pfn_GetSlaveHealthDegradedCount   GetSlaveHealthDegradedCount;
    pfn_RecoverSlaveMailboxHealth     RecoverSlaveMailboxHealth;

    pfn_GetRtPreemptCount             GetRtPreemptCount;
    pfn_GetRtPreemptPeakNs            GetRtPreemptPeakNs;
    pfn_GetBigGapUnknownCount         GetBigGapUnknownCount;
    pfn_GetSmiMsrAvailable            GetSmiMsrAvailable;
    pfn_GetWdkRtCpuIndex              GetWdkRtCpuIndex;
    pfn_GetWdkRxCpuIndex              GetWdkRxCpuIndex;
    pfn_GetWdkJitterInstrumentVer     GetWdkJitterInstrumentVer;
    pfn_GetWdkJitterHistBin           GetWdkJitterHistBin;
    pfn_GetWdkJitterTotalSamples      GetWdkJitterTotalSamples;
    pfn_GetWdkJitterMinNs             GetWdkJitterMinNs;
    pfn_GetWdkJitterLastWakeDeltaNs   GetWdkJitterLastWakeDeltaNs;
    pfn_GetWdkPathCountFast           GetWdkPathCountFast;
    pfn_GetWdkPathCountMed            GetWdkPathCountMed;
    pfn_GetWdkPathCountSlow           GetWdkPathCountSlow;
    pfn_GetWdkKtimerWakeNormalCnt     GetWdkKtimerWakeNormalCnt;
    pfn_GetWdkKtimerWakeOverrunCnt    GetWdkKtimerWakeOverrunCnt;
    pfn_GetWdkDispatchCycleMaxJitterNs GetWdkDispatchCycleMaxJitterNs;
    pfn_GetWdkDrainCycleMaxJitterNs   GetWdkDrainCycleMaxJitterNs;
    pfn_GetWdkDiagCounter             GetWdkDiagCounter;

    pfn_CiA402_GetTransitionCommand      CiA402_GetTransitionCommand;
    pfn_CiA402_RequestTransition         CiA402_RequestTransition;
    pfn_CiA402_FaultResetStep            CiA402_FaultResetStep;
    pfn_CiA402_GetSupportedDriveModes    CiA402_GetSupportedDriveModes;
    pfn_CiA402_IsModeSupported           CiA402_IsModeSupported;
    pfn_CiA402_GetQuickStopOption        CiA402_GetQuickStopOption;
    pfn_CiA402_SetQuickStopOption        CiA402_SetQuickStopOption;
    pfn_CiA402_GetShutdownOption         CiA402_GetShutdownOption;
    pfn_CiA402_SetShutdownOption         CiA402_SetShutdownOption;
    pfn_CiA402_GetDisableOperationOption CiA402_GetDisableOperationOption;
    pfn_CiA402_SetDisableOperationOption CiA402_SetDisableOperationOption;
    pfn_CiA402_GetHaltOption             CiA402_GetHaltOption;
    pfn_CiA402_SetHaltOption             CiA402_SetHaltOption;
    pfn_CiA402_GetFaultReactionOption    CiA402_GetFaultReactionOption;
    pfn_CiA402_SetFaultReactionOption    CiA402_SetFaultReactionOption;
    pfn_CiA402_GetErrorCode              CiA402_GetErrorCode;
    pfn_CiA402_GetErrorHistory           CiA402_GetErrorHistory;
    pfn_CiA402_ClearErrorHistory         CiA402_ClearErrorHistory;
    pfn_CiA402_SetHomingMethod           CiA402_SetHomingMethod;
    pfn_CiA402_GetHomingMethod           CiA402_GetHomingMethod;
    pfn_CiA402_GetSupportedHomingMethods CiA402_GetSupportedHomingMethods;
    pfn_CiA402_IsStandardHomingMethod    CiA402_IsStandardHomingMethod;

    pfn_EsmIsLegalTransition     EsmIsLegalTransition;
    pfn_EsmGetLegalTransitions   EsmGetLegalTransitions;
    pfn_EsmGetDefaultTimeoutMs   EsmGetDefaultTimeoutMs;
    pfn_EsmIsKnownAlStatusCode   EsmIsKnownAlStatusCode;
    pfn_EsmClassifyAlStatusCode  EsmClassifyAlStatusCode;
    pfn_EsmGetMasterClass        EsmGetMasterClass;

    pfn_MBGStart             MBGStart;
    pfn_MBGStop              MBGStop;
    pfn_MBGIsRunning         MBGIsRunning;
    pfn_MBGGetStats          MBGGetStats;
    pfn_MBGResetStats        MBGResetStats;
    pfn_MBGGetPort           MBGGetPort;
    pfn_MBGStartTcp          MBGStartTcp;
    pfn_MBGStopTcp           MBGStopTcp;
    pfn_MBGTcpIsRunning      MBGTcpIsRunning;
    pfn_MBGGetTcpPort        MBGGetTcpPort;
    pfn_MBGGetSelectedMaster MBGGetSelectedMaster;
    pfn_MBGSetSelectedMaster MBGSetSelectedMaster;

    pfn_DiagnoseNicHealth    DiagnoseNicHealth;
    pfn_VerifyNicHealth      VerifyNicHealth;
    pfn_AutoRecoverNic       AutoRecoverNic;

    pfn_coe_diag_poll_new_available coe_diag_poll_new_available;
    pfn_coe_diag_read_meta          coe_diag_read_meta;
    pfn_coe_diag_read_message       coe_diag_read_message;
    pfn_coe_diag_acknowledge        coe_diag_acknowledge;

    pfn_GetGroupActualWKC    GetGroupActualWKC;
    pfn_GetGroupDiag         GetGroupDiag;
    pfn_TraceLog             TraceLog;
    pfn_RecoverSlaveToOP     RecoverSlaveToOP;
    pfn_GetSlaveSMLength     GetSlaveSMLength;
    pfn_MDPAutoEnumerate     MDPAutoEnumerate;
    pfn_GetSlavePortLinkStatus GetSlavePortLinkStatus;
    pfn_SetDcSyncMode        SetDcSyncMode;
    pfn_GetDcSyncMode        GetDcSyncMode;
} dll_t;

#ifndef DLL_T_DEFINED
#define DLL_T_DEFINED
#endif

#define LOAD_DLL(ctx, path) load_dll_impl(ctx, path)
#define UNLOAD_DLL(ctx)     unload_dll_impl(ctx)

#define LOAD_FUNC(ctx, type, name) ((type)GET_PROC((ctx)->handle, #name))

static inline int verify_dll_integrity(const dll_t* ctx)
{
    if (!ctx || !ctx->handle) return 0;

    if (!ctx->Initialize || !ctx->SetNetwork || !ctx->SetState ||
        !ctx->Start || !ctx->Stop || !ctx->Dispose) {
        return 0;
    }

    if (!ctx->IsLicenseValid || !ctx->VerifyLicense) {
        return 0;
    }

    if (ctx->GetDllVersionInfo) {
        const version_info_t* ver = ctx->GetDllVersionInfo();

        if (!ver || (ver->major == 0 && ver->minor == 0 && ver->patch == 0 && ver->build == 0)) {
            return 0;
        }
    }

    return 1;
}

static inline int load_dll_impl(dll_t* ctx, const char* path)
{
    if (!ctx || !path) return 0;
    memset(ctx, 0, sizeof(dll_t));

    ctx->handle = LOAD_LIB(path);
    if (!ctx->handle) return 0;

    #define _DARRA_STRINGIFY(x) #x
    #define _DARRA_TOSTR(x) _DARRA_STRINGIFY(x)
    #define _BIND_PROC(field, export_name) do { \
        uintptr_t _darra_proc = (uintptr_t)GET_PROC(ctx->handle, export_name); \
        memcpy(&(ctx->field), &_darra_proc, sizeof(ctx->field)); \
    } while (0)
    #define _BIND(name) _BIND_PROC(name, "D_" _DARRA_TOSTR(ORD_##name))

    #define _BIND_ALIAS(field, export_name) _BIND_PROC(field, export_name)

    _BIND(Initialize);
    _BIND(InitializeSpecificMaster);
    _BIND(Dispose);
    _BIND(Start);
    _BIND(Stop);
    _BIND(GetMaxMasterInstances);

    _BIND(SetNetwork);
    _BIND(SetState);
    _BIND(SetStateWithTimeout);
    _BIND(SetSlaveStateWithTimeout);
    _BIND(SetStateSequence);
    _BIND(SetStateWithStartup);
    _BIND(GetLinkStatus);
    _BIND(GetSlaveState);
    _BIND(GetSlaveALStatusCode);

    _BIND(GetIO);
    _BIND(LockIOmap);
    _BIND(UnlockIOmap);
    _BIND(WriteSlaveOutput);
    _BIND(WriteSlaveOutputByte);
    _BIND(SetMutexProtection);
    _BIND(GetMutexProtection);

    _BIND(dx_sdo_write);
    _BIND(dx_sdo_read);
    _BIND(dx_sdo_read_ex);
    _BIND(dx_sdo_write_ex);
    _BIND(GetSlaveSDOList);
    _BIND(GetSlaveSDOListBasic);
    _BIND(GetSlavePointer_SDO);
    _BIND(GetSlavePointer_SDO_WithODList);
    _BIND(GetSlavePointer_SDO_Value);
    _BIND(GetSlavePointer_SDO_IndexValue);
    _BIND(GetMultiSlaveSDOList);
    _BIND(FreeMultiSlaveSDOList);

    _BIND(coe_get_od_list);
    _BIND(coe_get_object_desc);
    _BIND(coe_get_entry_desc);
    _BIND(coe_free_odlist);
    _BIND(coe_free_oelist);

    _BIND(AddStartupParameter);
    _BIND(AddStartupParameterBatch);
    _BIND(ClearStartupParameters);
    _BIND(GetStartupParameterCount);
    _BIND(ApplyStartupParameters);
    _BIND(ApplyStartupParametersAll);

    _BIND(LoadConfigJson);
    _BIND(AutoConfigureSM);
    _BIND(EcInit);
    _BIND(EcInitFromFile);
    _BIND(EcClose);

    _BIND(SetMasterDCCycleTime);
    _BIND(SetMasterLoopCycleTime);
    _BIND(SetSyncBySlaveIndex);
    _BIND(ConfigureDCAll);
    _BIND(UpdatePropagationDelays);
    _BIND(AutoCalculateDCShift);
    _BIND(EnableContinuousMeasurement);
    _BIND(EnableDriftCompensation);
    _BIND(SetDCAutoShiftEnabled);
    _BIND(GetDCAutoShiftEnabled);
    _BIND(GetSlavePropagationDelay);
    _BIND(GetMaxPropagationDelay);
    _BIND(GetSlaveSyncWindowStatus);
    _BIND(SetSyncWindowThreshold);
    _BIND(GetSyncWindowThreshold);
    _BIND(ResetSlaveSyncWindowStats);
    _BIND(GetMaxSyncDifference);
    _BIND(IsAllSlavesInSync);

    _BIND(SetSlaveGroup);
    _BIND(GetSlaveGroup);
    _BIND(SetGroupCycleDivider);
    _BIND(GetGroupCycleDivider);
    _BIND(SetGroupEnabled);
    _BIND(GetGroupEnabled);
    _BIND(GetGroupExpectedWKC);
    _BIND(GetActiveGroupCount);
    _BIND(GetGroupSlaveCount);

    _BIND(dx_soe_read);
    _BIND(dx_soe_write);
    _BIND(dx_soe_read_attributes);
    _BIND(dx_soe_read_name);
    _BIND(dx_soe_read_unit);
    _BIND(dx_soe_read_idn_list);
    _BIND(dx_soe_read_min_max);

    _BIND(dx_foe_read);
    _BIND(dx_foe_write);
    _BIND(dx_foe_read_ex);
    _BIND(dx_foe_write_ex);
    _BIND(dx_foe_set_progress_hook);
    _BIND(dx_foe_clear_progress_hook);

    _BIND(dx_eoe_set_ip);
    _BIND(dx_eoe_get_ip);
    _BIND(dx_eoe_send_frame);
    _BIND(dx_eoe_receive_frame);
    _BIND(dx_eoe_set_mac);
    _BIND(dx_eoe_get_mac);
    _BIND(dx_eoe_set_dns);
    _BIND(dx_eoe_get_dns);
    _BIND(dx_eoe_get_full_param);
    _BIND(dx_eoe_set_full_param);
    _BIND(dx_eoe_set_address_filter);
    _BIND(dx_eoe_get_address_filter);

    _BIND(dx_aoe_send_command);
    _BIND(dx_aoe_read_write);
    _BIND(dx_aoe_read_device_info);
    _BIND(dx_aoe_read_state);
    _BIND(dx_aoe_write_control);
    _BIND(dx_aoe_add_notification);
    _BIND(dx_aoe_del_notification);
    _BIND(dx_aoe_set_config);
    _BIND(dx_aoe_get_config);
    _BIND(dx_aoe_start_notification_listener);
    _BIND(dx_aoe_stop_notification_listener);
    _BIND(dx_aoe_is_notification_listening);
    _BIND(dx_aoe_register_notification);
    _BIND(dx_aoe_unregister_notification);

    _BIND(dx_voe_send);
    _BIND(dx_voe_receive);
    _BIND(dx_voe_send_raw);
    _BIND(dx_voe_receive_raw);
    _BIND(dx_voe_is_supported);

    _BIND(SetLogCallback);
    _BIND(SetCrashCallback);

    _BIND_ALIAS(RegisterPDOCyclicSync,            "D_" _DARRA_TOSTR(ORD_RegisterProcessDataCyclicCallbackSync));

    _BIND_ALIAS(RegisterStateChangeSync,          "D_" _DARRA_TOSTR(ORD_RegisterSlaveStateChangeCallbackSync));
    _BIND_ALIAS(RegisterStateChangeAsync,         "D_" _DARRA_TOSTR(ORD_RegisterSlaveStateChangeCallbackAsync));
    _BIND_ALIAS(RegisterEmergency,                "D_" _DARRA_TOSTR(ORD_RegisterEmergencyEventCallback));
    _BIND_ALIAS(RegisterDiscoverySync,            "D_" _DARRA_TOSTR(ORD_RegisterSlaveDiscoveryCallbackSync));
    _BIND_ALIAS(RegisterDiscoveryAsync,           "D_" _DARRA_TOSTR(ORD_RegisterSlaveDiscoveryCallbackAsync));
    _BIND_ALIAS(RegisterPDOFrameLoss,             "D_" _DARRA_TOSTR(ORD_RegisterPDOFrameLossCallback));
    _BIND_ALIAS(RegisterRedundancyChanged,        "D_" _DARRA_TOSTR(ORD_RegisterRedundancyModeChangedCallback));
    _BIND_ALIAS(RegisterPreOpReconfig,            "D_" _DARRA_TOSTR(ORD_RegisterSlavePreOpReconfigCallback));

    _BIND(SetDCSyncLostCallback);
    _BIND_ALIAS(RegisterSlaveIdentityMismatch,    "D_" _DARRA_TOSTR(ORD_RegisterSlaveIdentityMismatchCallback));
    _BIND_ALIAS(RegisterSlavePortLinkChanged,     "D_" _DARRA_TOSTR(ORD_RegisterSlavePortLinkChangedCallback));

    _BIND(AcknowledgeSlaveReplacement);

    _BIND(WriteSlaveDLPORT);
    _BIND(ReadSlaveDLPORT);

    _BIND(GetMasterState);
    _BIND(GetMasterStateCache);
    _BIND(GetSlave);
    _BIND(GetSlaveDetailedInfo);
    _BIND(GetCommunicationStats);
    _BIND(ResetCommunicationStats);
    _BIND(GetDetailedDiagnostics);
    _BIND(ResetDiagnostics);
    _BIND(GetDiagnosticsPointer);
    _BIND(GetSummaryPointer);
    _BIND(SetDiagnosticsEnabled);
    _BIND(GetDiagnosticsEnabled);
    _BIND(GetExpectedWKC);
    _BIND(SetExpectedWKC);
    _BIND(GetPacketLossRate);
    _BIND(GetLateFrameRate);
    _BIND(GetWdkPrimaryFrameTx);
    _BIND(GetWdkPrimaryFrameRx);
    _BIND(GetWdkSecondaryFrameTx);
    _BIND(GetWdkSecondaryFrameRx);
    _BIND(GetWdkPdoIdxDropCount);
    _BIND(GetSlaveLinkQuality);

    _BIND(RecordPDOCycleStart);
    _BIND(RecordWKC);
    _BIND(UpdateDiagnosticsSnapshot);
    _BIND(ResetSlavePortErrorCounters);
    _BIND(GetDllVersionInfo);
    _BIND(DumpSlaveStructOffsets);

    _BIND(GetMasterIdentity);
    _BIND(GetMasterDiagData);
    _BIND(ec_validate_config);
    _BIND(ec_perf_export_csv);
    _BIND(GetBreakPoints);
    _BIND(GetRingMode);
    _BIND(GetSecondaryLinkStatus);
    _BIND(ReadSlavePortErrorCounters);
    _BIND(ReadAllSlavePortErrorCounters);
    _BIND(GetSlavePortErrorStats);
    _BIND(UpdateDiagnosticsWithESCErrors);
    _BIND(GetDiagnosticsSnapshot);

    _BIND(GetSlaveWcState);
    _BIND(GetSlaveAlStatusMirror);
    _BIND(GetWcDeficit);
    _BIND(GetWcStateSeq);
    _BIND(GetMappedSlaveCount);
    _BIND(GetWkcActualMirror);
    _BIND(GetWkcExpectedMirror);

    _BIND(GetNetworkInfo);
    _BIND(GetNetworksPointer);
    _BIND(QuickSlaveCount);
    _BIND(QuickFindRedundantPairBatch);

    _BIND(ReadSlaveInfo);
    _BIND(GetScannedSlaveCount);
    _BIND(GetScannedSlaveInfo);
    _BIND(GetRingSlaveCount);

    _BIND(GetAvailableCpuCores);
    _BIND(SetMasterCpuAffinity);
    _BIND(SetProcessCpuAffinity);
    _BIND(SetPDOThreadCpuAffinity);
    _BIND(GetPDOThreadCpuAffinity);
    _BIND(ApplyRealtimeOptimizations);
    _BIND(RemoveRealtimeOptimizations);
    _BIND(GetRealtimeOptimizationsStatus);
    _BIND(GetTimingMode);
    _BIND(DarraValidateTimerAccuracy);

    _BIND(SetRedProcessdata);
    _BIND(GetRedProcessdata);
    _BIND(EnableRedundancy);
    _BIND(GetRedundancyStatus);
    _BIND(ForceRedundancyFailover);
    _BIND(CheckRedundancyHealth);

    _BIND(WriteSlaveRegister);
    _BIND(ReadSlaveRegister);
    _BIND(ConfigureSyncManager);
    _BIND(ConfigureFMMU);
    _BIND(EnableOutputSyncManager);
    _BIND(DisableOutputSyncManager);
    _BIND(GetSlaveOpOnlyFlag);
    _BIND(SetSlaveErrorAck);
    _BIND(GetSlaveDeviceEmulationFlag);

    _BIND(SetSlaveWatchdog);
    _BIND(SetSlavePdiWatchdog);
    _BIND(GetSlaveWatchdogConfig);
    _BIND(GetSlaveWatchdogStatus);
    _BIND(SetAllSlaveWatchdog);
    _BIND(SetAllSlavePdiWatchdog);

    _BIND(GetSlaveIdentity);
    _BIND(VerifySlaveIdentity);
    _BIND(VerifyAllSlaveIdentities);
    _BIND(SetSlaveOptional);
    _BIND(GetSlaveOptional);
    _BIND(SetSlaveSupportsFrameRepeat);
    _BIND(GetSlaveSupportsFrameRepeat);
    _BIND(GetSlaveNeedsStartupReconfig);
    _BIND(ClearSlaveNeedsStartupReconfig);

    _BIND(GetSlaveEsmTimeouts);
    _BIND(SetSlaveEsmTimeouts);

    _BIND(SetPDOLogging);
    _BIND(SetMailboxLogging);
    _BIND(SetDebugLogging);
    _BIND(CloseDebugLog);

    _BIND(GetPrimaryWKC);
    _BIND(GetSecondaryWKC);
    _BIND(GetPrimaryWKCEx);
    _BIND(GetSecondaryWKCEx);

    _BIND(FreeMemory);

    _BIND(IsWdkAvailable);
    _BIND(SetWdkMode);
    _BIND(GetWdkMode);
    _BIND(StartWdkRT);
    _BIND(StopWdkRT);

    _BIND(SetWdkPdOffload);
    _BIND(PiggybackRequest);
    _BIND(PiggybackResponse);

    _BIND(GetSlaveStateLive);
    _BIND(GetSlaveALStatusCodeLive);

    _BIND(SetLicenseExpiredCallback);
    _BIND(UnsetLicenseExpiredCallback);

    _BIND(SetUdpMode);
    _BIND(GetUdpMode);
    _BIND(IsUdpAvailable);

    _BIND(AbortScan);
    _BIND(ResetScanAbort);
    _BIND(AbortNetwork);
    _BIND(ResetAbortNetwork);
    _BIND(EmergencyCloseNics);

    _BIND(CiA402_ParseState);
    _BIND(CiA402_GetEnableCommand);
    _BIND(CiA402_SetMode);
    _BIND(CiA402_GetMode);
    _BIND(CiA402_ReadStatusWord);
    _BIND(CiA402_WriteControlWord);
    _BIND(CiA402_Enable);
    _BIND(CiA402_FaultReset);

    _BIND(EmcyGetHistory);
    _BIND(EmcyClearHistory);
    _BIND(EmcyGetCount);

    _BIND(PdoWriteInt8);
    _BIND(PdoWriteInt16);
    _BIND(PdoWriteInt32);
    _BIND(PdoWriteUint8);
    _BIND(PdoWriteUint16);
    _BIND(PdoWriteUint32);
    _BIND(PdoReadInt8);
    _BIND(PdoReadInt16);
    _BIND(PdoReadInt32);
    _BIND(PdoReadUint8);
    _BIND(PdoReadUint16);
    _BIND(PdoReadUint32);

    _BIND(PDOReadInputU8);
    _BIND(PDOReadInputI16);
    _BIND(PDOReadInputU16);
    _BIND(PDOReadInputI32);
    _BIND(PDOReadInputU32);
    _BIND(PDOReadInputF32);
    _BIND(PDOWriteOutputU8);
    _BIND(PDOWriteOutputI16);
    _BIND(PDOWriteOutputU16);
    _BIND(PDOWriteOutputI32);
    _BIND(PDOWriteOutputU32);
    _BIND(PDOWriteOutputF32);

    _BIND(PDOReadDirect);
    _BIND(PDOWriteDirect);
    _BIND(PDOBatchRead);
    _BIND(PDOBatchWrite);
    _BIND(GetPDOStats);
    _BIND(ResetPDOStats);
    _BIND(EnablePDOMonitoring);
    _BIND(IsPDOMonitoringEnabled);
    _BIND(GetPDOMapping);

    _BIND(GetPDOFrameLossStats);
    _BIND(ResetPDOFrameLossStats);

    _BIND(mbx_get_stats_by_master);
    _BIND(mbx_reset_stats_by_master);
    _BIND(mbx_submit_async_by_master);
    _BIND(mbx_wait_by_master);
    _BIND(mbx_cancel_by_master);
    _BIND(mbx_get_result_by_master);

    _BIND(GetTopology);
    _BIND(TopologyBuild);
    _BIND(TopologyGetChildren);
    _BIND(TopologyGetRoots);
    _BIND(GetSlaveActivePorts);
    _BIND(GetSlaveParent);

    _BIND(GetSerialNumber);
    _BIND(GetDeviceName);
    _BIND(GetUserEmail);
    _BIND(GetWindowsProductKey);
    _BIND(GetDriverList);
    _BIND_ALIAS(VerifyLicense,     "D_1586");
    _BIND_ALIAS(InvalidateLicense, "D_1590");
    _BIND_ALIAS(IsLicenseValid,    "D_1589");

    _BIND(GetSlaveConfigAddr);
    _BIND(GetSlaveAliasAddr);
    _BIND(GetSlaveVendorId);
    _BIND(GetSlaveProductCode);
    _BIND(GetSlaveRevision);
    _BIND(GetSlaveSerialNumber);
    _BIND(GetSlaveOutputBits);
    _BIND(GetSlaveOutputBytes);
    _BIND(GetSlaveOutputOffset);
    _BIND(GetSlaveInputBits);
    _BIND(GetSlaveInputBytes);
    _BIND(GetSlaveInputOffset);
    _BIND(GetSlaveMailboxProto);
    _BIND(GetSlaveMailboxWriteLength);
    _BIND(GetSlaveMailboxWriteOffset);
    _BIND(GetSlaveMailboxReadLength);
    _BIND(GetSlaveMailboxReadOffset);
    _BIND(GetSlaveHasDC);
    _BIND(GetSlaveDCActive);
    _BIND(GetSlaveDCCycle0);
    _BIND(GetSlaveDCCycle1);
    _BIND(GetSlaveDCShift);
    _BIND(GetSlaveDCNext);
    _BIND(GetSlaveDCPrevious);
    _BIND(GetSlaveDCReceiveTimeA);
    _BIND(GetSlaveDCReceiveTimeB);
    _BIND(GetSlaveDCReceiveTimeC);
    _BIND(GetSlaveDCReceiveTimeD);

    _BIND(GetSlavePhysicalType);
    _BIND(GetSlaveBlockLRW);
    _BIND(GetSlaveEep8Byte);
    _BIND(GetSlaveEepPDI);
    _BIND(GetSlaveCoEDetails);
    _BIND(GetSlaveFoEDetails);
    _BIND(GetSlaveEoEDetails);
    _BIND(GetSlaveSoEDetails);
    _BIND(GetSlaveIsLost);
    _BIND(GetSlaveEbusCurrent);
    _BIND(GetSlaveTopologyType);
    _BIND(GetSlaveEntryPort);
    _BIND(GetSlaveParentPort);
    _BIND(GetSlaveName);
    _BIND(GetSlaveDeviceName);

    _BIND(GetSlaveOutputStartBit);
    _BIND(GetSlaveInputStartBit);
    _BIND(GetSlaveFMMU0Function);
    _BIND(GetSlaveFMMU1Function);
    _BIND(GetSlaveFMMU2Function);
    _BIND(GetSlaveFMMU3Function);
    _BIND(GetSlaveMbxCount);
    _BIND(GetSlavePDelay);
    _BIND(GetSlaveDCParentPort);
    _BIND(GetSlaveConsumedPorts);

    _BIND(GetSlaveParentStation);

    _BIND(GetSlaveHasEsi);
    _BIND(SetSlaveEsiFile);
    _BIND(GetSlaveEsiVersion);
    _BIND(GetSlaveHasMDP);
    _BIND(GetSlaveVendorName);

    _BIND(GetSlaveRedundancyActivated);
    _BIND(GetSlavePrimaryLinkBroken);
    _BIND(GetSlaveSecondaryLinkBroken);

    _BIND(DebugSlaveHasDC);

    _BIND(dx_fsoe_init_connection);
    _BIND(dx_fsoe_close_connection);
    _BIND(dx_fsoe_get_status);
    _BIND(dx_fsoe_request_state);
    _BIND(dx_fsoe_get_state);
    _BIND(dx_fsoe_reset);
    _BIND(dx_fsoe_write_safe_output);
    _BIND(dx_fsoe_read_safe_input);
    _BIND(dx_fsoe_download_parameters);
    _BIND(dx_fsoe_set_failsafe_output);
    _BIND(dx_fsoe_check_watchdog);
    _BIND(dx_fsoe_get_last_error);
    _BIND(dx_fsoe_clear_error);
    _BIND(dx_fsoe_is_slave_capable);
    _BIND(dx_fsoe_get_connection_count);
    _BIND(dx_fsoe_process_cycle);

    _BIND(DxSafeMdpInitConnection);
    _BIND(DxSafeMdpCloseConnection);
    _BIND(DxSafeMdpGetStatus);
    _BIND(DxSafeMdpRequestState);
    _BIND(DxSafeMdpGetState);
    _BIND(DxSafeMdpReset);
    _BIND(DxSafeMdpWriteSafeOutput);
    _BIND(DxSafeMdpReadSafeInput);
    _BIND(DxSafeMdpDownloadParameters);
    _BIND(DxSafeMdpSetFailsafeOutput);
    _BIND(DxSafeMdpCheckWatchdog);
    _BIND(DxSafeMdpGetLastError);
    _BIND(DxSafeMdpClearError);
    _BIND(DxSafeMdpGetSlaveConnectionCount);
    _BIND(DxSafeMdpDetectConnections);
    _BIND(DxSafeMdpGetDeviceAddress);
    _BIND(DxSafeMdpGetModuleCommParam);
    _BIND(DxSafeMdpGetModuleDiagnosis);

    _BIND(HotConnectAddGroup);
    _BIND(HotConnectRemoveGroup);
    _BIND(HotConnectGetGroupStatus);
    _BIND(HotConnectEnumerate);
    _BIND(HotConnectClearAll);
    _BIND(HotConnectGetGroupCount);

    _BIND(dx_eoe_send_frame_ex);
    _BIND(dx_eoe_set_receive_hook);
    _BIND(dx_eoe_clear_receive_hook);

    _BIND(dx_voe_start_notification_listener);
    _BIND(dx_voe_stop_notification_listener);
    _BIND(dx_voe_is_notification_listening);
    _BIND(dx_voe_register_notification);
    _BIND(dx_voe_unregister_notification);

    _BIND(GetMasterDCTime);
    _BIND_ALIAS(GetReferenceClockSlave, "D_" _DARRA_TOSTR(ORD_GetReferenceClockSlaveIndex));

    _BIND(dx_fsoe_validate_conn_id);

    _BIND(dx_foe_request_cancel);
    _BIND(dx_foe_clear_cancel);
    _BIND(dx_foe_set_busy_hook);

    _BIND_ALIAS(GetDriverVersion,             "D_" _DARRA_TOSTR(ORD_GetDriverVersion));
    _BIND_ALIAS(InvalidateDriverVersionCache, "D_" _DARRA_TOSTR(ORD_InvalidateDriverVersionCache));
    _BIND_ALIAS(EnsureDriversRunning,         "D_" _DARRA_TOSTR(ORD_EnsureDriversRunning));

    _BIND(DarraEcat_KernelProbe);
    _BIND(DarraEcat_KernelStatusMessage);
    _BIND(DarraEcat_KernelInstallerUrl);

    _BIND(GetCycleEventHandle);
    _BIND(GetCycleEventName);
    _BIND(WaitForCycleEvent);
    _BIND(GetCycleCount);

    _BIND(UnregisterProcessDataCyclicCallbackSync);

    _BIND(UnregisterSlaveStateChangeCallbackSync);
    _BIND(UnregisterSlaveStateChangeCallbackAsync);
    _BIND(UnregisterEmergencyEventCallback);
    _BIND(UnregisterSlaveDiscoveryCallbackSync);
    _BIND(UnregisterSlaveDiscoveryCallbackAsync);
    _BIND(UnregisterPDOFrameLossCallback);
    _BIND(UnregisterRedundancyModeChangedCallback);
    _BIND(UnregisterSlavePreOpReconfigCallback);
    _BIND(UnregisterSlaveIdentityMismatchCallback);

    _BIND(UnregisterSlavePortLinkChangedCallback);
    _BIND(UnsetLogCallback);
    _BIND(UnsetCrashCallback);
    _BIND(UnsetDCSyncLostCallback);

    _BIND(AL_StatusCode_GetDescriptionChinese);
    _BIND(AL_StatusCode_GetRecoveryHintChinese);

    _BIND(GetMasterAlstatRefresh);
    _BIND(GetPiggybackDiagCounters);
    _BIND(GetPiggybackDiagCounters2);
    _BIND(GetTopoPriIntact);
    _BIND(GetTopoSecIntact);

    _BIND(HotSwapRebuild);

    _BIND(GetSlaveFreeRunDemoted);
    _BIND(GetSlaveMailboxHealth);
    _BIND(GetSlaveHealthDegradedCount);
    _BIND(RecoverSlaveMailboxHealth);

    _BIND(GetRtPreemptCount);
    _BIND(GetRtPreemptPeakNs);
    _BIND(GetBigGapUnknownCount);
    _BIND(GetSmiMsrAvailable);
    _BIND(GetWdkRtCpuIndex);
    _BIND(GetWdkRxCpuIndex);
    _BIND(GetWdkJitterInstrumentVer);
    _BIND(GetWdkJitterHistBin);
    _BIND(GetWdkJitterTotalSamples);
    _BIND(GetWdkJitterMinNs);
    _BIND(GetWdkJitterLastWakeDeltaNs);
    _BIND(GetWdkPathCountFast);
    _BIND(GetWdkPathCountMed);
    _BIND(GetWdkPathCountSlow);
    _BIND(GetWdkKtimerWakeNormalCnt);
    _BIND(GetWdkKtimerWakeOverrunCnt);
    _BIND(GetWdkDispatchCycleMaxJitterNs);
    _BIND(GetWdkDrainCycleMaxJitterNs);
    _BIND(GetWdkDiagCounter);

    _BIND(CiA402_GetTransitionCommand);
    _BIND(CiA402_RequestTransition);
    _BIND(CiA402_FaultResetStep);
    _BIND(CiA402_GetSupportedDriveModes);
    _BIND(CiA402_IsModeSupported);
    _BIND(CiA402_GetQuickStopOption);
    _BIND(CiA402_SetQuickStopOption);
    _BIND(CiA402_GetShutdownOption);
    _BIND(CiA402_SetShutdownOption);
    _BIND(CiA402_GetDisableOperationOption);
    _BIND(CiA402_SetDisableOperationOption);
    _BIND(CiA402_GetHaltOption);
    _BIND(CiA402_SetHaltOption);
    _BIND(CiA402_GetFaultReactionOption);
    _BIND(CiA402_SetFaultReactionOption);
    _BIND(CiA402_GetErrorCode);
    _BIND(CiA402_GetErrorHistory);
    _BIND(CiA402_ClearErrorHistory);
    _BIND(CiA402_SetHomingMethod);
    _BIND(CiA402_GetHomingMethod);
    _BIND(CiA402_GetSupportedHomingMethods);
    _BIND(CiA402_IsStandardHomingMethod);

    _BIND(EsmIsLegalTransition);
    _BIND(EsmGetLegalTransitions);
    _BIND(EsmGetDefaultTimeoutMs);
    _BIND(EsmIsKnownAlStatusCode);
    _BIND(EsmClassifyAlStatusCode);
    _BIND(EsmGetMasterClass);

    _BIND(MBGStart);
    _BIND(MBGStop);
    _BIND(MBGIsRunning);
    _BIND(MBGGetStats);
    _BIND(MBGResetStats);
    _BIND(MBGGetPort);
    _BIND(MBGStartTcp);
    _BIND(MBGStopTcp);
    _BIND(MBGTcpIsRunning);
    _BIND(MBGGetTcpPort);
    _BIND(MBGGetSelectedMaster);
    _BIND(MBGSetSelectedMaster);

    _BIND(SIIReadWord);
    _BIND(SIIWriteWord);

    _BIND(DiagnoseNicHealth);
    _BIND(VerifyNicHealth);
    _BIND(AutoRecoverNic);

    _BIND(coe_diag_poll_new_available);
    _BIND(coe_diag_read_meta);
    _BIND(coe_diag_read_message);
    _BIND(coe_diag_acknowledge);

    _BIND(GetGroupActualWKC);
    _BIND(GetGroupDiag);
    _BIND(TraceLog);
    _BIND(RecoverSlaveToOP);
    _BIND(GetSlaveSMLength);
    _BIND(MDPAutoEnumerate);
    _BIND(GetSlavePortLinkStatus);
    _BIND(SetDcSyncMode);
    _BIND(GetDcSyncMode);

    #undef _BIND
    #undef _BIND_ALIAS
    #undef _DARRA_TOSTR
    #undef _DARRA_STRINGIFY

    if (!ctx->Initialize || !ctx->SetNetwork || !ctx->SetState) {
        FREE_LIB(ctx->handle);
        ctx->handle = NULL;
        return 0;
    }

    if (!verify_dll_integrity(ctx)) {
        FREE_LIB(ctx->handle);
        memset(ctx, 0, sizeof(dll_t));
        return 0;
    }

    mbx_init_all_protocols(ctx);

    {
        extern void darra_log_driver_compatibility(void);

#       ifndef DARRA_SKIP_DRIVER_LOG
        darra_log_driver_compatibility();
#       endif
    }

    return 1;
}

static inline void unload_dll_impl(dll_t* ctx)
{
    if (ctx && ctx->handle) {
        FREE_LIB(ctx->handle);
        memset(ctx, 0, sizeof(dll_t));
    }
}

#endif

#ifdef __cplusplus
}
#endif

#endif
