Purpose
The LM-X Python wrapper is a thin Python interface over the native LM-X client library. It provides Pythonic access to the whole LM-X API.
Package Contents
The wheel contains:
- Python package:
lmx(client.py,_ffi.py,_marshal.py,_callbacks.py,types.py,errors.py) - Embedded native LM-X client library (platform-specific):
liblmx.so(Linux/Unix)liblmx.dylib(macOS)liblmx.dll(Windows)
The wheel is non-pure (root_is_pure = False) and platform-tagged.
Prerequisites
- Python
>= 3.8 - LM-X SDK build output for your target platform
- Matching Python bitness and SDK target bitness (32-bit vs 64-bit)
Build the Wheel
Recommended (from SDK root)
Build the SDK as usual; wheel build is part of the SDK makefile flow:
...
python/lmx-*.whlpython/wheel_build.log
Build only the wheel target
- Unix-like:
make build_python_wheel - Windows:
nmake build_python_wheel
Manual script invocation
From SDK root:
| Code Block |
|---|
python3 python/build_sdk_wheel.py \ --platform linux_x64 \ --library linux_x64/liblmx.so \ --output-dir python \ --venv python/.venv_wheel |
...
--platformmust match LM-X host directory naming (for examplelinux_x64,win64_x64,darwin_universal).- The script skips build (exit code
0) when prerequisites are not met and logsSKIPPED:reason topython/wheel_build.log.
Install and Start
Install the generated wheel
From SDK examples/python:
pip install ../../python/lmx-*.whl
Run example scripts
| Code Block |
|---|
python3 local.py python3 network.py python3 callbacks.py python3 licstat.py python3 clientstore.py python3 trial.py python3 admin.py |
...
- Unix:
make run_local(andrun_network,run_callbacks,run_licstat,run_clientstore,run_trial,run_admin,run_all) - Windows:
nmake run_local(same target set)
Minimal Usage Example
| Code Block | ||||||
|---|---|---|---|---|---|---|
| ||||||
from lmx import LMX_STATUS, LmxClient, LmxSettings
FEATURE = "f2"
with LmxClient() as client:
status = client.init()
if status != int(LMX_STATUS.LMX_SUCCESS):
raise RuntimeError(f"LMX_Init failed: {status}")
# Setup license path
client.set_option(LmxSettings.LMX_OPT_LICENSE_PATH, "6200@localhost")
# Checkout one license
status = client.checkout(FEATURE, 1, 0, 1)
if status != int(LMX_STATUS.LMX_SUCCESS):
error = client.get_error_message()
raise RuntimeError(f"LMX_Checkout failed: status={status}, error={error}")
# Checkin the license
status = client.checkin(FEATURE, 1)
if status != int(LMX_STATUS.LMX_SUCCESS):
raise RuntimeError(f"LMX_Checkin failed: {client.get_error_message()}") |
How It Works
LmxClientis a thread-safe OO facade over LM-X C APIs.- The wrapper loads native LM-X symbols through
ctypes.CDLL(lmx/_ffi.py). - Method calls map 1:1 to native exports (
LMX_Init,LMX_Checkout,LMX_Checkin, etc.). - Complex C structs are converted into Python dictionaries/dataclasses by marshal helpers (
lmx/_marshal.py). - Python callback options are converted to C function pointers.
- Status codes are returned as integers compatible with
LMX_STATUSenum values.
Native Library Resolution Order
When creating LmxClient() without explicit library_path, the wrapper searches in this order:
...
If no valid library is found, LmxUsageError is raised with attempted paths.
Troubleshooting
Wheel not generated
Symptoms:
- No
python/lmx-*.whlafter build
...
- Inspect
python/wheel_build.logforSKIPPED:messages. - Verify Python interpreter exists and is callable.
- Verify interpreter bitness matches target platform bitness.
- Verify native library path provided to build script exists.
Could not locate LM-X client library
Symptoms:
- Import/initialization fails with path-resolution error
...
- Ensure wheel was installed successfully (
pip show lmx). - If overriding library location, set absolute
LMX_PYTHON_LIBRARY_PATH. - If using
LmxClient(library_path=...), pass an absolute file path. - Confirm file name matches platform (
.so,.dylib,.dll).
Callback-related crashes or unexpected behavior
Checks:
- Register callbacks via
set_option()only. - Keep callback signatures compatible with expected LM-X callback shapes.
- Do not bypass
LmxClientinternals for callback pointer handling.