dev
vmc.dll API
C 风格导出的虚拟机台控制接口,任何语言都能 P/Invoke。
它是什么
vmc.dll(virtual machine control)把虚拟机台暴露成一组 C 函数。
用途有两个:自动化测试(在 CI 里跑标定流程)和教学(用 Python 写脚本驱动设备)。
接口是 C 风格导出,没有 C++ 名字修饰,没有 COM,没有 .NET 依赖——
ctypes、P/Invoke、JNA、LabVIEW 都能直接调。
生命周期
// 返回句柄,失败返回 NULL
VMC_HANDLE vmc_open(const char* machineConfigPath);
void vmc_close(VMC_HANDLE h);
// 最近一次错误,线程局部
int vmc_last_error(VMC_HANDLE h);
const char* vmc_last_error_message(VMC_HANDLE h);所有函数返回 0 表示成功,负数表示错误码(见错误码)。
轴
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 表示不等待立即返回,-1 表示一直等到到位。
相机
// 抓一帧到调用方提供的缓冲区;bufSize 不足时返回 VMC_E_BUFFER_TOO_SMALL
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);图像是 8 位灰度,行优先,stride 可能大于 width(对齐)。
IO
int vmc_io_read(VMC_HANDLE h, int channel, int* outValue);
int vmc_io_write(VMC_HANDLE h, int channel, int value);标定链
// 同步跑完一条链;结果以 JSON 写入 outJson
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 取值:C1-pixel-size、C2-hand-eye、C3-intrinsics、
C4-galvo-field、C5-z-focus、C6-stage-geometry。
返回的 JSON 含真值对照(虚拟设备才有):
{
"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 }
}误差模型注入
测试里最有用的一组接口:故意把设备调坏,看你的程序会不会发现。
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 }版本与兼容
int vmc_version(char* outSemver, int size);接口是版本化的:1.x 内只增不改,破坏性变更只出现在大版本。
你的测试代码应该在启动时检查主版本号。
线程
一个 VMC_HANDLE 不是线程安全的。多线程请各开各的句柄,或者自己加锁。
虚拟设备本身支持多实例并行(CI 里并行跑测试没问题)。
最后更新: 2026/9/21
这页有帮助吗?