Vyntek
规格机器视觉规格

C# 适配 / 绑定(MVP)

www 工作副本 · M5(Arden · 2026-10-21 Asia/Shanghai)
双轨:本页已迁入 Vyntek www;mvdocs csharp-binding 仍在线对照。
M5-10(Alive 已拍):MVP 显示封装 只认 Controls 轨;Skia/Avalonia 不双开(后续可选宿主)。
实现边界:对拍 bindings tip 769d997。Vyntek.Bindings 含 PixelImageInfo 与 IGray8 / IRgb24 / IBgr24 / IDepth16(PixelImageHandle 实现它们)。Vyntek.Controls 有 Share/OpenRead、预算、TryGet*AtView、Unload/Remount,无真实渲染。缺 DLL → DllNotFoundException;缺符号 → EntryPointNotFoundException。host-integration 全文仍在 mvdocs。
关联:image-display · cpp-headers · host-integration(mvdocs) · TC-DISP 薄摘 · 预览 http://127.0.0.1:8792

本文是独立短文,避免把绑定细则塞进 cpp-headers。与 overview / cpp-headers 已有「PInvoke 倾向」表述一致,不另立第二套绑定默认。

定位

层语言职责
vyntek::toolflow / vyntek::imagingC++编排与像素/句柄权威
本绑定(MVP)PInvoke 薄层把公开 C API / 导出入口投影到托管;不复制执行语义
ImageDisplay 等C#UI/显示封装;只消费绑定交出的句柄/投影
C++/CLI—非默认;不作为 MVP 并列路径

依赖方向:

ImageDisplay / 编辑器 / Runner(C#)
        │
        ▼
  PInvoke 绑定(opaque handle + Dispose)
        │
        ▼
  C++ vyntek::imaging / vyntek::toolflow(公开头)

C++ 不 #include UI;绑定 不 在托管侧重写 ToolFlow 执行器或第二套 Imaging。

MVP:PInvoke 规则

  1. 薄:每个导出入口对应一个明确的原生函数;托管侧少逻辑,复杂编排仍在 C++。
  2. 可控:显式入口、显式错误码/HRESULT 风格约定;避免隐式最终化器代替业务 Release。
  3. 与头文件对齐:可绑定的符号须能从 cpp-headers.md 公开头推出;detail/ 不对绑定暴露。
  4. C++/CLI 非默认:若未来需要,须单独论证;不得与 PInvoke 并列为 MVP「随便选一个」。

句柄跨边界

规则说明
Opaque handle托管侧持有 IntPtr / 强类型 SafeHandle 包装的不透明值;不把 C++ 对象布局、vtable、STL 容器直接暴露给 C#
所有权清晰绑定返回的句柄:要么「调用方拥有、须 Release/Dispose」,要么「借用、禁止 Release」——二者在 API 名与文档中写死;禁止共享所有权模糊期
Release / Dispose拥有型句柄实现 IDisposable(或等价);Dispose 恰好一次调用原生 Release;重复 Dispose 无害;未 Dispose 不得依赖 GC 最终器作为主路径(可作诊断兜底,不作正确性依赖)
投影类型可选 IPixelImage 等为句柄的托管投影(见 overview);语义仍以 C++ 为准,投影不得放宽 ReadOnly / 寿命
观察与执行分离经绑定订阅 LastRun / 输出观察(见 output-inspection.md)永不隐式 Run;与显示只观察一致

示意(非已发布 ABI):

// 示意:拥有型 opaque handle;Dispose = 原生 Release 恰好一次
public sealed class PixelImageHandle : SafeHandle
{
    // IsInvalid / ReleaseHandle → native vyntek_imaging_handle_release(...)
    // 禁止把内部指针交给第二处「也负责释放」的所有者
}

// 借用:TryOpen 得到的临时读视图另有 View.Dispose,不释放底层图像所有权

ImageDisplay(C#)如何消费

  • image-display.md 保持 C# API(SetImage 等)。
  • 像素来自 C++ PixelImageHandle,经本绑定投影后交给控件;控件申请读/快照/脱离仍遵守成像/内存专题。
  • 不在 C++ 写 Avalonia/Skia UI;不让 ImageDisplay 成为编排 Cancel / 停相机的入口(toolflow §7.4.3)。

与相关文档的对齐

文档对齐点
overview.md「MVP 托管绑定倾向 PInvoke;C++/CLI 非默认」;Imaging 权威在 C++
cpp-headers.md绑定层仅桥公开头;本文展开句柄跨边界,cpp-headers 保持 include 树不膨胀
toolflow.md进程内 C++ 库 + PInvoke;观察钩子不驱动执行
examples.md编排/成像示例 C++;ImageDisplay 示例 C#(T12)
output-inspection.md观察事件经绑定上抛时仍用 ToolId;不驱动 Run
host-integration.mdR7:headless / C# 显示宿主同核;示意 vyntek_toolflow_* / vyntek_imaging_* 与本文 PInvoke 对齐;停止矩阵宿主侧分派

明确不做(MVP)

  • 以 C++/CLI 作为默认或并列默认绑定。
  • 托管与原生「共同拥有」同一句柄且无唯一 Release 点。
  • 在绑定层实现第二套 ToolFlow / 像素池。
  • 把 MPF / 旧 DAG / .vpp 术语带入绑定 API。

文档状态:设计草案(2026-10-21,Asia/Shanghai)。T11 Alive 拍板:MVP=PInvoke;C++/CLI 非默认;opaque handle + Release/Dispose;ImageDisplay 仅 C# 经本绑定消费。与 overview / cpp-headers / toolflow v1.9 / host-integration.md(R7)对齐。


实现对拍(bindings tip 769d997 · 按实)

表面按实
布局bindings/csharp/{Vyntek.Native, Vyntek.Bindings, Vyntek.Controls, Vyntek.Controls.Tests, Vyntek.Smoke} · net10.0
双库名vyntek_toolflow / vyntek_imaging
契约头include/vyntek/capi/vyntek_exports.h(NON-STABLE)
句柄PixelImageHandle : SafeHandle, IPixelImage;Dispose→handle_release;Share 独立拥有
像素取样Imaging.TryGet* → try_get_*;Depth16 返回 (ok, raw, isValid)
会话预览AcquisitionSession.TryLatest;空 = OK + null
ImageDisplay见 image-display.md;无 C++ UI;MVP = Controls(M5-10)

仍缺口:无真实渲染;TC-DISP 未验收。Skia/Avalonia 接通属 M5-10 非拦。

文档状态:www 工作副本(2026-10-21 Asia/Shanghai)。T11 MVP=PInvoke。bindings tip 769d997。

On this page