VendorLibrary
VendorLibrary is the abstract base class for all dynamically loaded vendor
driver wrappers. Blackchirp is built and distributed without compile-time
dependencies on vendor SDKs; instead, each VendorLibrary subclass uses
QLibrary to locate and load the vendor library at runtime. If the library
is absent or cannot be loaded, Blackchirp starts normally and the dependent
hardware drivers report themselves as unavailable.
The loading sequence is:
Try the user-provided path (
setUserProvidedPath), if set.Try user-specified search directories (
setUserSearchPaths), then platform-specific default paths (defaultSearchPaths), if automatic discovery is enabled.Resolve function pointers by calling the subclass
loadFunctions()implementation.Validate that all required symbols were found.
The staged-configuration API separates UI interaction from live hardware use.
UI code calls setStagedUserProvidedPath, setStagedSearchPaths, and
setStagedAutoDiscoveryEnabled to accumulate changes without affecting
running hardware, then calls applyChanges() to promote the staged
settings, persist them, and reload the library. revertChanges() discards
any staged edits. hasUnstagedChanges() allows the surrounding dialog to
enable or disable its Apply button. The LibraryStatusWidget in the
Application Settings dialog uses this API to manage library paths safely
without requiring a hardware restart until the user explicitly applies the
changes.
Hardware drivers that depend on a vendor library register the
dependency with REGISTER_LIBRARY (see HardwareRegistry).
The HardwareRegistry tracks these dependencies so HardwareManager
can destroy and recreate affected hardware objects around a library reload.
Concrete subclasses
LabjackLibraryLoads the LabJack U3 driver. On Linux and macOS the driver is the LJUSB transport library (
liblabjackusb.so/.dylib); on Windows it is the UD high-level library (LabJackUD.dll, 64-bit). TheBC::Labjackfacade inlabjackdriver.habstracts the platform difference and is the preferred entry point for hardware code. The cross-platform architecture is described in Vendor Libraries.SpectrumLibraryLoads the Spectrum Instrumentation driver (
spcm_linux/spcm64.dll). Used by M4i digitizer drivers for FTMW acquisition. Because the Spectrum library maintains global state, a single instance is enforced via the singleton pattern. M4i driver code reaches the resolved symbols through the singleton accessor:SpectrumLibrary &lib = SpectrumLibrary::instance(); if (lib.isAvailable()) { void *handle = lib.spcm_hOpen("/dev/spcm0"); // ... use other Spectrum functions }
API Reference
-
class VendorLibrary : public QObject, public SettingsStorage
Subclassed by LabjackLibrary, SpectrumLibrary
Public Functions
-
explicit VendorLibrary(const QString &libraryKey, QObject *parent = nullptr)
Construct a VendorLibrary with the given settings key.
- Parameters:
libraryKey – SettingsStorage key used to persist this library’s configuration
parent – Parent QObject for ownership; defaults to none.
-
virtual ~VendorLibrary() = default
Destroy the VendorLibrary and release any loaded library resources.
-
virtual bool isAvailable() const = 0
Check if the vendor library is available and loaded.
- Returns:
true if library is loaded and all functions resolved
-
virtual QString errorString() const = 0
Get error message if library loading failed.
- Returns:
Error string describing why library is not available
-
virtual QString libraryName() const = 0
Get the base name of the library being loaded.
- Returns:
Base library name (e.g., “spcm”, “labjackusb”)
-
virtual QStringList platformLibraryNames() const = 0
Get platform-specific library names to try.
This allows handling libraries that have different names on different platforms (e.g., “spcm_linux” on Linux, “spcm64.dll” on Windows)
- Returns:
List of library names with platform-specific variations
-
virtual QStringList defaultSearchPaths() const = 0
Get default search paths for automatic discovery.
This should return platform-specific default paths where the library is typically installed. User-specified paths take priority over these.
- Returns:
List of default search paths for this library type
-
inline virtual QString getVersionInfo() const
Get library version information.
This method attempts to query version information from the loaded library. Implementation is library-specific and may require temporary device access.
- Returns:
Version string if available, empty string if not available or not supported
-
virtual QString getInstallationInstructions() const = 0
Get platform-specific installation instructions for this library.
This method returns detailed, platform-specific instructions for installing the vendor library. The instructions should include download links, installation commands, and common troubleshooting information tailored to the current platform.
- Returns:
HTML-formatted installation instructions for the current platform
-
QString loadedLibraryPath() const
Get the full path where library was found (if loaded successfully)
- Returns:
Full path to loaded library, empty if not loaded
-
inline bool wasLoadingAttempted() const
Check if library loading was attempted.
- Returns:
true if loading was attempted (successfully or not)
-
void setUserProvidedPath(const QString &path)
Set user-provided library path.
This path takes priority over automatic discovery. If the path is invalid or the library cannot be loaded, automatic discovery will be used as fallback (if enabled).
- Parameters:
path – Full path to library file provided by user
-
QString getUserProvidedPath() const
Get user-provided library path.
- Returns:
User-specified library path, empty if none set
-
void addUserSearchPath(const QString &path)
Add user-specified search path.
User-specified search paths are tried before default search paths.
- Parameters:
path – Directory path to add to search paths
-
void setUserSearchPaths(const QStringList &paths)
Set user-specified search paths.
- Parameters:
paths – List of directory paths to search
-
QStringList getUserSearchPaths() const
Get user-specified search paths.
- Returns:
List of user-specified search directories
-
void setAutoDiscoveryEnabled(bool enabled)
Enable or disable automatic discovery.
When disabled, only user-provided paths are used. When enabled (default), automatic discovery is used if user-provided paths fail.
- Parameters:
enabled – Whether to use automatic discovery as fallback
-
bool isAutoDiscoveryEnabled() const
Check if automatic discovery is enabled.
- Returns:
true if automatic discovery is enabled
-
bool reloadLibrary()
Force reload of library with current settings.
This can be called after changing user settings to attempt loading with the new configuration.
- Returns:
true if library was successfully loaded
-
void setStagedUserProvidedPath(const QString &path)
Set staged user-provided library path.
This modifies the staged configuration without immediately affecting the active configuration used by hardware. Changes must be applied via applyChanges() to take effect.
- Parameters:
path – Full path to library file provided by user
-
void setStagedSearchPaths(const QStringList &paths)
Set staged user-specified search paths.
This modifies the staged configuration without immediately affecting the active configuration used by hardware.
- Parameters:
paths – List of directory paths to search
-
void setStagedAutoDiscoveryEnabled(bool enabled)
Set staged automatic discovery setting.
This modifies the staged configuration without immediately affecting the active configuration used by hardware.
- Parameters:
enabled – Whether to use automatic discovery as fallback
-
QString getStagedUserProvidedPath() const
Get staged user-provided library path.
- Returns:
Staged user-specified library path, empty if none set
-
QStringList getStagedSearchPaths() const
Get staged user-specified search paths.
- Returns:
List of staged user-specified search directories
-
bool isStagedAutoDiscoveryEnabled() const
Check if staged automatic discovery is enabled.
- Returns:
true if staged automatic discovery is enabled
-
bool hasUnstagedChanges() const
Check if there are unstaged changes.
- Returns:
true if staged configuration differs from active configuration
-
bool applyChanges()
Apply staged changes to active configuration.
This promotes the staged configuration to become the active configuration, saves the settings to persistent storage, and reloads the library with the new configuration.
- Returns:
true if changes were applied successfully and library reloaded
-
void revertChanges()
Revert staged changes to match active configuration.
This discards any staged changes and resets the staged configuration to match the current active configuration.
-
QString getActiveUserProvidedPath() const
Get active user-provided library path.
- Returns:
Active user-specified library path, empty if none set
-
QStringList getActiveSearchPaths() const
Get active user-specified search paths.
- Returns:
List of active user-specified search directories
-
bool isActiveAutoDiscoveryEnabled() const
Check if active automatic discovery is enabled.
- Returns:
true if active automatic discovery is enabled
Protected Functions
-
bool loadLibrary()
Attempt to load library using platform-specific names and paths.
This method tries each platform-specific library name in combination with each search path until the library loads successfully. It handles both absolute paths and library names for system path searching.
- Returns:
true if library was successfully loaded
-
QFunctionPointer resolveFunction(const char *functionName)
Resolve a function symbol to a function pointer.
This is a convenience method for subclasses to resolve function symbols. The library must be successfully loaded before calling this method.
- Parameters:
functionName – Name of function symbol to resolve
- Returns:
Function pointer or nullptr if not found
-
virtual void loadFunctions() = 0
Called by subclasses to load their specific function pointers.
Subclasses must implement this method to resolve all required function symbols after the library has been successfully loaded. If any required function cannot be resolved, this method should set d_libraryLoaded to false and update d_errorString with appropriate error information.
Protected Attributes
-
QLibrary d_library
Qt library loader
-
bool d_libraryLoaded
Whether library is loaded and ready
-
bool d_loadingAttempted
Whether loading was attempted
-
QString d_errorString
Error message if loading failed
-
QStringList d_attemptedPaths
Paths that were tried during loading
-
QString d_libraryKey
Settings key for this library
-
QString d_activeUserPath
Active user-provided library path
-
QStringList d_activeSearchPaths
Active user search paths
-
bool d_activeAutoDiscovery
Active auto-discovery setting
-
QString d_stagedUserPath
Staged user-provided library path
-
QStringList d_stagedSearchPaths
Staged user search paths
-
bool d_stagedAutoDiscovery
Staged auto-discovery setting
-
bool d_hasUnstagedChanges
Track if staging differs from active
Private Functions
-
QStringList buildSearchPathList() const
Build complete search path priority list.
- Returns:
Ordered list of paths to try (user paths first, then defaults)
-
void saveSuccessfulLoad(const QString &successfulPath)
Save successful load information to settings.
- Parameters:
successfulPath – Path that successfully loaded the library
Private Slots
-
void onLibraryDestroyed()
Handle library unloading.
Connected to QLibrary destroyed signal to clean up state when library is unloaded (e.g., during application shutdown).
-
explicit VendorLibrary(const QString &libraryKey, QObject *parent = nullptr)
-
class LabjackLibrary : public VendorLibrary
Public Types
-
typedef float (*LJUSB_GetLibraryVersion_t)(void)
-
typedef unsigned int (*LJUSB_GetDevCount_t)(unsigned long ProductID)
-
typedef void *(*LJUSB_OpenDevice_t)(unsigned int DevNum, unsigned int dwReserved, unsigned long ProductID)
-
typedef void (*LJUSB_CloseDevice_t)(void *hDevice)
-
typedef unsigned long (*LJUSB_Write_t)(void *hDevice, const unsigned char *pBuff, unsigned long count)
-
typedef unsigned long (*LJUSB_Read_t)(void *hDevice, unsigned char *pBuff, unsigned long count)
-
typedef bool (*LJUSB_IsHandleValid_t)(void *hDevice)
-
typedef bool (*LJUSB_ResetConnection_t)(void *hDevice)
Public Functions
-
inline virtual bool isAvailable() const override
Check if the LabJack driver library is loaded and ready.
- Returns:
true if library symbols were resolved successfully
-
inline virtual QString errorString() const override
Get error message if library loading failed.
- Returns:
Error string describing why the library is not available
-
virtual QString getVersionInfo() const override
Get library version string.
- Returns:
Version string from the loaded driver, or empty string if unavailable
-
virtual QString getInstallationInstructions() const override
Get platform-specific installation instructions for the LabJack driver.
- Returns:
HTML-formatted instructions for installing the LabJack driver on the current platform
-
inline virtual QString libraryName() const override
Get the base name of the LabJack driver library.
- Returns:
Base library name string
-
virtual QStringList platformLibraryNames() const override
Get platform-specific library file names to try when loading.
- Returns:
List of library names with platform-specific variations
-
virtual QStringList defaultSearchPaths() const override
Get default search paths for automatic LabJack driver discovery.
- Returns:
List of default directories to search for the library
Public Members
-
LJUSB_GetLibraryVersion_t LJUSB_GetLibraryVersion = nullptr
-
LJUSB_GetDevCount_t LJUSB_GetDevCount = nullptr
-
LJUSB_OpenDevice_t LJUSB_OpenDevice = nullptr
-
LJUSB_CloseDevice_t LJUSB_CloseDevice = nullptr
-
LJUSB_Write_t LJUSB_Write = nullptr
-
LJUSB_Read_t LJUSB_Read = nullptr
-
LJUSB_IsHandleValid_t LJUSB_IsHandleValid = nullptr
-
LJUSB_ResetConnection_t LJUSB_ResetConnection = nullptr
Public Static Functions
-
static LabjackLibrary &instance()
Get singleton instance of LabjackLibrary.
- Returns:
Reference to the single LabjackLibrary instance
Protected Functions
-
virtual void loadFunctions() override
Resolve LabJack driver function symbols after the library has loaded.
Private Functions
-
explicit LabjackLibrary(QObject *parent = nullptr)
-
~LabjackLibrary() override = default
-
LabjackLibrary(const LabjackLibrary&) = delete
-
LabjackLibrary &operator=(const LabjackLibrary&) = delete
Private Static Attributes
-
static LabjackLibrary *s_instance = nullptr
-
typedef float (*LJUSB_GetLibraryVersion_t)(void)
-
class SpectrumLibrary : public VendorLibrary
Dynamic loader for the Spectrum Instrumentation driver library (
spcm_linux/spcm64.dll).Singleton, because the Spectrum library maintains global state that cannot be duplicated. Used by the M4i digitizer implementations.
Public Types
-
typedef void *(*spcm_hOpen_t)(const char *szDeviceName)
Open Spectrum device Function pointer for spcm_hOpen()
-
typedef void (*spcm_vClose_t)(void *hDevice)
Close Spectrum
device
Function pointer for
spcm_vClose()
-
typedef std::int32_t (*spcm_dwSetParam_i32_t)(void *hDevice, std::int32_t lRegister, std::int32_t lValue)
Set 32-bit integer parameter Function pointer for spcm_dwSetParam_i32()
-
typedef std::int32_t (*spcm_dwGetParam_i32_t)(void *hDevice, std::int32_t lRegister, std::int32_t *plValue)
Get 32-bit integer parameter Function pointer for spcm_dwGetParam_i32()
-
typedef std::int32_t (*spcm_dwSetParam_i64_t)(void *hDevice, std::int32_t lRegister, std::int64_t llValue)
Set 64-bit integer parameter Function pointer for spcm_dwSetParam_i64()
-
typedef std::int32_t (*spcm_dwGetParam_i64_t)(void *hDevice, std::int32_t lRegister, std::int64_t *pllValue)
Get 64-bit integer parameter Function pointer for spcm_dwGetParam_i64()
-
typedef std::int32_t (*spcm_dwDefTransfer_i64_t)(void *hDevice, std::int32_t lBufType, std::int32_t lDirection, std::int32_t lNotifySize, void *pvDataBuffer, std::int64_t qwOffset, std::int64_t qwLength)
Define transfer buffer Function pointer for spcm_dwDefTransfer_i64()
-
typedef std::int32_t (*spcm_dwInvalidateBuf_t)(void *hDevice, std::int32_t lBufType)
Start transfer Function pointer for spcm_dwInvalidateBuf()
-
typedef std::int32_t (*spcm_dwGetErrorInfo_i32_t)(void *hDevice, std::int32_t *plErrorReg, std::int32_t *plErrorValue, char *szErrorText)
Get error information Function pointer for spcm_dwGetErrorInfo_i32()
Public Functions
-
inline virtual bool isAvailable() const override
Check if the Spectrum driver library is loaded and ready.
- Returns:
true if library symbols were resolved successfully
-
inline virtual QString errorString() const override
Get error message if library loading failed.
- Returns:
Error string describing why the library is not available
-
inline virtual QString libraryName() const override
Get the base name of the Spectrum driver library.
- Returns:
Base library name string (“spcm”)
-
virtual QStringList platformLibraryNames() const override
Get platform-specific library file names to try when loading.
- Returns:
List of library names with platform-specific variations
-
virtual QStringList defaultSearchPaths() const override
Get default search paths for automatic Spectrum driver discovery.
- Returns:
List of default directories to search for the library
-
virtual QString getVersionInfo() const override
Get Spectrum driver version string.
- Returns:
Version string from the loaded driver, or empty string if unavailable
-
virtual QString getInstallationInstructions() const override
Get platform-specific installation instructions for the Spectrum driver.
- Returns:
HTML-formatted instructions for installing the Spectrum driver on the current platform
Public Members
-
spcm_hOpen_t spcm_hOpen = nullptr
-
spcm_vClose_t spcm_vClose = nullptr
-
spcm_dwSetParam_i32_t spcm_dwSetParam_i32 = nullptr
-
spcm_dwGetParam_i32_t spcm_dwGetParam_i32 = nullptr
-
spcm_dwSetParam_i64_t spcm_dwSetParam_i64 = nullptr
-
spcm_dwGetParam_i64_t spcm_dwGetParam_i64 = nullptr
-
spcm_dwDefTransfer_i64_t spcm_dwDefTransfer_i64 = nullptr
-
spcm_dwInvalidateBuf_t spcm_dwInvalidateBuf = nullptr
-
spcm_dwGetErrorInfo_i32_t spcm_dwGetErrorInfo_i32 = nullptr
Public Static Functions
-
static SpectrumLibrary &instance()
Get singleton instance of SpectrumLibrary.
- Returns:
Reference to the single SpectrumLibrary instance
Protected Functions
-
virtual void loadFunctions() override
Resolve Spectrum driver function symbols after the library has loaded.
Private Functions
-
explicit SpectrumLibrary(QObject *parent = nullptr)
-
~SpectrumLibrary() = default
-
SpectrumLibrary(const SpectrumLibrary&) = delete
-
SpectrumLibrary &operator=(const SpectrumLibrary&) = delete
Private Static Attributes
-
static SpectrumLibrary *s_instance = nullptr
-
typedef void *(*spcm_hOpen_t)(const char *szDeviceName)