.NET Integration in vvvv gamma
.csproj Configuration for vvvv Plugins
Minimal .csproj for a vvvv gamma C# plugin:
CODEBLOCK0
Key settings:
- - Target framework:
net8.0 (required for vvvv gamma 6+) - Output path: Point to
lib/net8.0/ relative to your .vl document - AppendTargetFrameworkToOutputPath: Set to
false so DLLs go directly to the output folder
How vvvv Uses C# Code
There are two workflows for integrating C# with a .vl document:
Source project reference (live reload): The .vl document references a .csproj. vvvv compiles .cs source files itself via Roslyn into in-memory assemblies — no dotnet build needed. On every .cs file save, vvvv detects the change and recompiles automatically. The output path in .csproj is not involved during live development; it is used for NuGet packaging and deployment.
Binary reference (no live reload): The .vl document references a pre-compiled DLL or NuGet package. To apply C# changes, rebuild externally (dotnet build) and restart vvvv. This is the standard workflow for larger projects and stable libraries.
Shaders (.sdsl files) always live-reload regardless of workflow.
For AI agents: regardless of workflow, run dotnet build to verify your code compiles — you cannot see vvvv's compiler output. For source project references, vvvv picks up changes on file save automatically (no restart needed). For binary references, dotnet build is required and the user must restart vvvv.
Required Global Usings
CODEBLOCK1
Required Assembly Attribute
For vvvv to discover your ProcessNodes and static methods:
CODEBLOCK2
Without this, your nodes will not appear in the vvvv node browser.
NuGet Package Sources
Add these to your NuGet.config for vvvv packages:
CODEBLOCK3
NuGet Packaging
To distribute your plugin as a NuGet package:
CODEBLOCK4
The .nuspec should reference your .vl document, compiled DLLs, shader files, and help patches.
Common VL Packages
| Package | Purpose |
|---|
| INLINECODE12 | Core types, ProcessNode attribute, Spread |
| INLINECODE13 |
3D rendering, shader integration |
|
VL.Stride.Runtime | Stride engine runtime |
|
VL.Core.Import | ImportAsIs attribute |
|
VL.Lib.Collections | Spread, SpreadBuilder |
|
VL.Skia | 2D rendering (Skia graphics engine) |
|
VL.Fuse | GPU visual programming (shader graph) |
|
VL.IO.OSC | Open Sound Control protocol |
|
VL.IO.MQTT | MQTT messaging |
|
VL.IO.Redis | Redis key-value store |
|
VL.OpenCV | Computer vision (OpenCV bindings) |
|
VL.MediaPipe | MediaPipe ML pipelines (hand, face, pose) |
|
VL.Audio | Audio synthesis and I/O (NAudio-based) |
|
VL.Devices.AzureKinect | Azure Kinect / Orbbec depth cameras |
For a full catalog, see vvvv.org/packs.
Vector Types & SIMD Strategy
- - Internal hot paths: Use
System.Numerics.Vector3/Vector4/Quaternion (SIMD via AVX/SSE) - External API (Update method params): Use
Stride.Core.Mathematics types (required by VL) - Zero-cost conversion between them:
CODEBLOCK5
These types have identical memory layouts, making Unsafe.As a zero-cost operation.
IDisposable and Resource Management
Any node holding native/unmanaged resources must implement IDisposable:
CODEBLOCK6
vvvv calls Dispose() when the node is removed or the document closes.
Async Patterns in vvvv
Since Update() runs on the main thread at 60 FPS, long-running operations must be async:
CODEBLOCK7
Blittable Structs for GPU/Network
For data that crosses GPU or network boundaries, use blittable structs:
CODEBLOCK8
Rules: no reference type fields, no bool (use int), explicit layout. Enables Span<T> access and zero-copy serialization via MemoryMarshal.
Referencing vvvv-Loaded DLLs
When referencing DLLs already loaded by vvvv (e.g., VL.Fuse), use <Private>false</Private> to prevent copying:
CODEBLOCK9
Build Commands
Build a vvvv plugin project:
CODEBLOCK10
Build an entire solution:
CODEBLOCK11
C++/CLI Interop
For wrapping native C/C++ libraries:
CODEBLOCK12
C++/CLI projects require Visual Studio (not dotnet CLI) for building.
Common Package Version Ranges
When referencing vvvv packages, use wildcard versions to stay compatible:
CODEBLOCK13
This ensures your plugin works with any patch release of the target vvvv version.
Directory.Build.props
For multi-project solutions, centralize settings:
CODEBLOCK14
COM Interop Pitfalls (DX11/DX12)
When working with COM objects (Direct3D, DXGI):
- -
ComPtr<T> is a struct with no finalizer — if it goes out of scope without Dispose(), the COM ref leaks - Always return ComPtrs to pools or explicitly Dispose them
- INLINECODE39 fails if any command list on the queue is in recording state
For forwarding .NET libraries into VL (wrapping without new types, pin modifications, event wrapping), see forwarding.md.
Threading Considerations
- -
Update() is always called on the VL main thread - Use
SynchronizationContext to post back to the VL thread from background tasks:
CODEBLOCK15
vvvv gamma 中的 .NET 集成
vvvv 插件的 .csproj 配置
vvvv gamma C# 插件的最小 .csproj 文件:
xml
net8.0
..\..\lib\net8.0\
false
关键设置:
- - 目标框架:net8.0(vvvv gamma 6+ 必需)
- 输出路径:指向相对于 .vl 文档的 lib/net8.0/
- AppendTargetFrameworkToOutputPath:设置为 false,使 DLL 直接输出到目标文件夹
vvvv 如何使用 C# 代码
有两种将 C# 与 .vl 文档集成的工作流程:
源码项目引用(热重载):.vl 文档引用一个 .csproj。vvvv 通过 Roslyn 自行编译 .cs 源文件为内存中的程序集——无需 dotnet build。每次保存 .cs 文件时,vvvv 会自动检测更改并重新编译。在实时开发过程中不涉及 .csproj 中的输出路径;该路径用于 NuGet 打包和部署。
二进制引用(无热重载):.vl 文档引用预编译的 DLL 或 NuGet 包。要应用 C# 更改,需在外部重新构建(dotnet build)并重启 vvvv。这是大型项目和稳定库的标准工作流程。
着色器(.sdsl 文件)无论采用哪种工作流程,始终支持热重载。
对于 AI 代理:无论采用哪种工作流程,请运行 dotnet build 以验证代码是否可编译——您无法看到 vvvv 的编译器输出。对于源码项目引用,vvvv 会在文件保存时自动获取更改(无需重启)。对于二进制引用,需要 dotnet build,且用户必须重启 vvvv。
必需的全局引用
csharp
global using VL.Core;
global using VL.Core.Import;
global using VL.Lib.Collections;
必需的程序集属性
为了让 vvvv 发现您的 ProcessNode 和静态方法:
csharp
[assembly: ImportAsIs]
缺少此属性,您的节点将不会出现在 vvvv 节点浏览器中。
NuGet 包源
将以下内容添加到您的 NuGet.config 以获取 vvvv 包:
xml
NuGet 打包
要将您的插件作为 NuGet 包分发:
bash
nuget pack MyPlugin/deployment/MyPlugin.nuspec
.nuspec 应引用您的 .vl 文档、编译后的 DLL、着色器文件和帮助补丁。
常见 VL 包
| 包 | 用途 |
|---|
| VL.Core | 核心类型、ProcessNode 属性、Spread |
| VL.Stride |
3D 渲染、着色器集成 |
| VL.Stride.Runtime | Stride 引擎运行时 |
| VL.Core.Import | ImportAsIs 属性 |
| VL.Lib.Collections | Spread、SpreadBuilder |
| VL.Skia | 2D 渲染(Skia 图形引擎) |
| VL.Fuse | GPU 可视化编程(着色器图) |
| VL.IO.OSC | Open Sound Control 协议 |
| VL.IO.MQTT | MQTT 消息传递 |
| VL.IO.Redis | Redis 键值存储 |
| VL.OpenCV | 计算机视觉(OpenCV 绑定) |
| VL.MediaPipe | MediaPipe 机器学习管线(手部、面部、姿态) |
| VL.Audio | 音频合成与输入/输出(基于 NAudio) |
| VL.Devices.AzureKinect | Azure Kinect / Orbbec 深度相机 |
完整目录请参见 vvvv.org/packs。
向量类型与 SIMD 策略
- - 内部热点路径:使用 System.Numerics.Vector3/Vector4/Quaternion(通过 AVX/SSE 实现 SIMD)
- 外部 API(Update 方法参数):使用 Stride.Core.Mathematics 类型(VL 要求)
- 两者之间的零成本转换:
csharp
using System.Runtime.CompilerServices;
// Stride → System.Numerics(零成本重新解释)
ref var numericsVec = ref Unsafe.As(ref strideVec);
// System.Numerics → Stride(零成本重新解释)
ref var strideVec = ref Unsafe.As(ref numericsVec);
这些类型具有相同的内存布局,使得 Unsafe.As 成为零成本操作。
IDisposable 与资源管理
任何持有原生/非托管资源的节点必须实现 IDisposable:
csharp
[ProcessNode]
public class NativeWrapper : IDisposable
{
private IntPtr _handle;
public NativeWrapper()
{
_handle = NativeLib.Create();
}
public void Update(out int result)
{
result = NativeLib.Process(_handle);
}
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
NativeLib.Destroy(_handle);
_handle = IntPtr.Zero;
}
}
}
当节点被移除或文档关闭时,vvvv 会调用 Dispose()。
vvvv 中的异步模式
由于 Update() 在主线程上以 60 FPS 运行,长时间运行的操作必须异步执行:
csharp
[ProcessNode]
public class AsyncLoader
{
private Task? _loadTask;
private string _cachedResult = ;
public void Update(
out string result,
out bool isLoading,
string url = ,
bool trigger = false)
{
if (trigger && (loadTask == null || loadTask.IsCompleted))
{
_loadTask = Task.Run(() => LoadFromUrl(url));
}
isLoading = loadTask != null && !loadTask.IsCompleted;
if (_loadTask?.IsCompletedSuccessfully == true)
cachedResult = loadTask.Result;
result = _cachedResult;
}
}
用于 GPU/网络的可复制结构体
对于跨越 GPU 或网络边界的数据,请使用可复制结构体:
csharp
[StructLayout(LayoutKind.Sequential)]
public struct AnimationBlendState
{
public int ClipIndex1; // 4 字节
public float ClipTime1; // 4 字节
public int ClipIndex2; // 4 字节
public float ClipTime2; // 4 字节
public float BlendWeight; // 4 字节
}
规则:无引用类型字段,无 bool(使用 int),显式布局。支持 Span 访问和通过 MemoryMarshal 实现零拷贝序列化。
引用 vvvv 加载的 DLL
当引用已由 vvvv 加载的 DLL(例如 VL.Fuse)时,使用 false 防止复制:
xml
..\..\path\to\Fuse.dll
false
构建命令
构建 vvvv 插件项目:
bash
dotnet build src/MyPlugin.csproj -c Release
构建整个解决方案:
bash
dotnet build src/MyPlugin.sln -c Release
C++/CLI 互操作
用于包装原生 C/C++ 库:
bash
msbuild MyCLIWrapper/MyCLIWrapper.vcxproj /p:Configuration=Release /p:Platform=x64
C++/CLI 项目需要 Visual Studio(而非 dotnet CLI)进行构建。
常见包版本范围
引用 vvvv 包时,使用通配符版本以保持兼容性:
xml
这确保您的插件与目标 vvvv 版本的