Skip to content
PreciSim
dev

vmc.dll API

A C-style control interface to the virtual machine, callable from any language.

What it is

vmc.dll (virtual machine control) exposes the virtual machine as a set of C functions. Two uses: automated testing (run calibration procedures in CI) and teaching (drive devices from a Python script).

Plain C exports — no C++ name mangling, no COM, no .NET dependency. ctypes, P/Invoke, JNA and LabVIEW all call it directly.

Lifetime

VMC_HANDLE vmc_open(const char* machineConfigPath);   // NULL on failure
void       vmc_close(VMC_HANDLE h);
 
int         vmc_last_error(VMC_HANDLE h);
const char* vmc_last_error_message(VMC_HANDLE h);

Every function returns 0 on success and a negative error code otherwise.

Axes

int vmc_axis_home(VMC_HANDLE h, const char* axisId);
int vmc_axis_move_abs(VMC_HANDLE h, const char* axisId, double targetMm, int waitMs);
int vmc_axis_move_rel(VMC_HANDLE h, const char* axisId, double deltaMm, int waitMs);
int vmc_axis_position(VMC_HANDLE h, const char* axisId, double* outMm);
int vmc_axis_stop(VMC_HANDLE h, const char* axisId);

waitMs = 0 returns immediately; -1 waits for in-position.

Camera

int vmc_cam_grab(VMC_HANDLE h, const char* camId,
                 unsigned char* buf, int bufSize,
                 int* outWidth, int* outHeight, int* outStride);
 
int vmc_cam_set_exposure(VMC_HANDLE h, const char* camId, double us);
int vmc_cam_set_gain(VMC_HANDLE h, const char* camId, double db);

Images are 8-bit grey, row-major; stride may exceed width because of alignment.

IO

int vmc_io_read(VMC_HANDLE h, int channel, int* outValue);
int vmc_io_write(VMC_HANDLE h, int channel, int value);

Calibration

int vmc_calib_run(VMC_HANDLE h, const char* procedureId,
                  const char* paramsJson,
                  char* outJson, int outJsonSize);
 
int vmc_calib_get(VMC_HANDLE h, const char* procedureId,
                  char* outJson, int outJsonSize);

procedureId is one of C1-pixel-size, C2-hand-eye, C3-intrinsics, C4-galvo-field, C5-z-focus, C6-stage-geometry.

The returned JSON includes the truth comparison (virtual devices only):

{
  "procedure": "C1-pixel-size",
  "ok": true,
  "solved": { "mmPerPx": 0.019823, "thetaRad": 0.0041, "skew": 1.6e-4 },
  "truth":  { "mmPerPx": 0.019841, "thetaRad": 0.0039 },
  "verify": { "deviationMm": 0.018, "toleranceMm": 0.05, "pass": true },
  "residual": { "rmsPx": 0.081, "maxPx": 0.213 }
}

Fault injection

The most useful group for testing: break a device deliberately and see whether your software notices.

int vmc_fault_set(VMC_HANDLE h, const char* deviceId, const char* faultJson);
int vmc_fault_clear(VMC_HANDLE h, const char* deviceId);
{ "backlashUm": 50, "noiseScale": 4.0, "k1": -0.08, "stuckAt": null }

Versioning

int vmc_version(char* outSemver, int size);

The interface is versioned: additive within 1.x, breaking changes only on a major release. Test code should check the major version at start-up.

Threading

A VMC_HANDLE is not thread safe. Use one handle per thread, or your own lock. Multiple virtual machine instances can run in parallel, so CI can run tests concurrently.

Last updated: Sep 21, 2026
Was this page helpful?