跳到主要内容

MethodBuilder

概述

OPC UA Call 服务 (Part 4 §5.11.2) 要求把入参打包成 Variant[]DarraUa_MethodBuilder_* 提供链式 C API, 自动按类型选 Variant 编码。

API

函数类别读写说明
DarraUa_MethodBuilder_New(ua, obj, mid, &out_b)构造绑定到方法
DarraUa_MethodBuilder_Free(b)释放析构
DarraUa_MethodBuilder_LoadInputArgs(b)链式读 InputArguments 描述
DarraUa_MethodBuilder_ArgByName(b, name, value)链式按名设值
DarraUa_MethodBuilder_ArgByIndex(b, index, value)链式按索引设值
DarraUa_MethodBuilder_Invoke(b, &out_outs, &out_n)终端调用, 返回 StatusCode

valueDarraUa_Variant*, 用 DarraUa_Variant_Set* 系列填充。

代码示例

#include <opcua.h>

int main() {
DarraUa_Session* ua;
DarraUa_Session_New("opc.tcp://localhost:4840", &ua);
DarraUa_Session_Connect(ua);

// 1) 流式调用
DarraUa_MethodBuilder* b;
DarraUa_MethodBuilder_New(ua, "ns=2;s=Robot", "ns=2;s=Robot.MoveTo", &b);
DarraUa_MethodBuilder_LoadInputArgs(b);

DarraUa_Variant vx, vy, vs;
DarraUa_Variant_SetDouble(&vx, 100.0);
DarraUa_Variant_SetDouble(&vy, 200.0);
DarraUa_Variant_SetInt32(&vs, 50);

DarraUa_MethodBuilder_ArgByName(b, "x", &vx);
DarraUa_MethodBuilder_ArgByName(b, "y", &vy);
DarraUa_MethodBuilder_ArgByName(b, "speed", &vs);

DarraUa_Variant* outs = NULL;
size_t n_outs = 0;
DarraUa_StatusCode st = DarraUa_MethodBuilder_Invoke(b, &outs, &n_outs);
if (st != UA_GOOD) fprintf(stderr, "MoveTo 失败 0x%08X\n", st);

DarraUa_FreeVariants(outs, n_outs);
DarraUa_MethodBuilder_Free(b);

// 2) 按索引
DarraUa_MethodBuilder* b2;
DarraUa_MethodBuilder_New(ua, "ns=2;s=Calc", "ns=2;s=Calc.Add", &b2);
DarraUa_Variant a, c;
DarraUa_Variant_SetDouble(&a, 3.14);
DarraUa_Variant_SetDouble(&c, 2.71);
DarraUa_MethodBuilder_ArgByIndex(b2, 0, &a);
DarraUa_MethodBuilder_ArgByIndex(b2, 1, &c);
DarraUa_Variant* o2 = NULL;
size_t n2 = 0;
DarraUa_MethodBuilder_Invoke(b2, &o2, &n2);
double sum;
DarraUa_Variant_GetDouble(&o2[0], &sum);
printf("Add → %f\n", sum);
DarraUa_FreeVariants(o2, n2);
DarraUa_MethodBuilder_Free(b2);

DarraUa_Session_Free(ua);
return 0;
}

与 Call 的对比

// 旧写法: 手撸 Variant[]
DarraUa_Variant inputs[3];
DarraUa_Variant_SetDouble(&inputs[0], 100.0);
DarraUa_Variant_SetDouble(&inputs[1], 200.0);
DarraUa_Variant_SetInt32(&inputs[2], 50); // 类型?
DarraUa_Variant* outs;
size_t n;
DarraUa_Session_Call(ua, "ns=2;s=Robot", "ns=2;s=Robot.MoveTo",
inputs, 3, &outs, &n);

// 新写法: MethodBuilder (类型由 ArgByName 内部记录)
DarraUa_MethodBuilder* b;
DarraUa_MethodBuilder_New(ua, "ns=2;s=Robot", "ns=2;s=Robot.MoveTo", &b);
// ... ArgByName / Invoke

实现限制

  • LoadInputArgs 依赖 ExtensionObject 解码
  • 不支持复杂结构入参
  • Invoke 失败返回 Bad* StatusCode, 不打印日志, 业务自己判读

跨语言对照

C#PythonJavaC++RustC
MethodBuilderMethodBuilderMethodBuilderMethodBuilderMethodBuilderDarraUa_MethodBuilder_*
.Arg(name, value).arg(name, value).arg(name, value).Arg(name, value).arg(name, value)DarraUa_MethodBuilder_ArgByName

下一步