跳到主要内容

Variant (C)

DarraUa_Variant* 是 OPC UA 的通用值容器, 覆盖 OPC UA 全部内置数据类型. SDK 用它在 C 与 Stack 之间传值.

配套

公共 API

类别属性类型访问说明
生命周期DarraUa_Variant_New()DarraUa_Variant*RW新建空 Variant; 用 _Delete 释放
DarraUa_Variant_Delete(v)voidW释放 Variant 句柄 (v 为 NULL 时安全)
类型 / 状态DarraUa_Variant_GetType(v)DarraUa_BuiltinTypeR内置类型枚举
DarraUa_Variant_IsScalar(v)int32_tR1 = 标量, 0 = 数组
DarraUa_Variant_IsArray(v)int32_tR1 = 数组
DarraUa_Variant_GetArrayLength(v)int32_tR数组长度, -1 = 标量

标量 Set / Get

DarraUa_Variant* v = DarraUa_Variant_New();

DarraUa_Variant_SetBoolean(v, 1); /* 1 = true */
DarraUa_Variant_SetByte(v, 255);
DarraUa_Variant_SetInt16(v, 42);
DarraUa_Variant_SetInt32(v, 42);
DarraUa_Variant_SetUInt32(v, 42u);
DarraUa_Variant_SetInt64(v, 42LL);
DarraUa_Variant_SetFloat(v, 3.14f);
DarraUa_Variant_SetDouble(v, 3.14);
DarraUa_Variant_SetString(v, "hello");
DarraUa_Variant_SetDateTime(v, 132680064000000000LL); /* 100ns since 1601 */

/* Get */
int32_t b = 0; DarraUa_Variant_GetBoolean(v, &b);
int32_t i = 0; DarraUa_Variant_GetInt32(v, &i);
double d = 0.0; DarraUa_Variant_GetDouble(v, &d);
const char* s = DarraUa_Variant_GetString(v); /* 内部指针, 不释放 */
DarraUa_DateTime ts = DarraUa_Variant_GetDateTime(v);

DarraUa_Variant_Delete(v);

每个 Set* 返回 int32_t: 1 = OK, 0 = 类型不匹配 / 失败. 每个 Get* 返回 1 表示成功写入, 类型不符返回 0 不修改 out 参数.


QualifiedName / LocalizedText

/* QualifiedName */
DarraUa_Variant_SetQualifiedName(v, /*ns*/ 2, "Counter");
uint16_t ns = 0; const char* name = NULL;
DarraUa_Variant_GetQualifiedName(v, &ns, &name); /* name 生命周期 = v */

/* LocalizedText */
DarraUa_Variant_SetLocalizedText(v, "zh-CN", "温度");
const char* loc = NULL; const char* text = NULL;
DarraUa_Variant_GetLocalizedText(v, &loc, &text);

数组 Set / Get

double arr[] = { 1.0, 2.0, 3.0 };
DarraUa_Variant_SetDoubleArray(v, arr, 3);

int32_t len = DarraUa_Variant_GetArrayLength(v); /* 3 */
double out[16] = {0};
DarraUa_Variant_GetDoubleArray(v, out, 16);

/* 字符串数组 */
const char* names[] = { "a", "b", "c" };
DarraUa_Variant_SetStringArray(v, names, 3);

const char* one = DarraUa_Variant_GetStringArrayItem(v, 0); /* 内部指针, 不释放 */

支持的数组类型 (深拷贝, Variant 自管释放):

DarraUa_Variant_SetBooleanArray(v, ints,  n);
DarraUa_Variant_SetInt32Array (v, ints, n);
DarraUa_Variant_SetUInt32Array (v, uints, n);
DarraUa_Variant_SetInt64Array (v, i64s, n);
DarraUa_Variant_SetFloatArray (v, fs, n);
DarraUa_Variant_SetDoubleArray (v, ds, n);
DarraUa_Variant_SetStringArray (v, strs, n);

Get*Arrayout_capacity < length 时不拷贝, 返回所需 length, 调用方扩容再调一次.


BuiltinType 完整清单

typedef enum {
DARRA_UA_TYPE_NULL = 0,
DARRA_UA_TYPE_BOOLEAN = 1,
DARRA_UA_TYPE_SBYTE = 2,
DARRA_UA_TYPE_BYTE = 3,
DARRA_UA_TYPE_INT16 = 4,
DARRA_UA_TYPE_UINT16 = 5,
DARRA_UA_TYPE_INT32 = 6,
DARRA_UA_TYPE_UINT32 = 7,
DARRA_UA_TYPE_INT64 = 8,
DARRA_UA_TYPE_UINT64 = 9,
DARRA_UA_TYPE_FLOAT = 10,
DARRA_UA_TYPE_DOUBLE = 11,
DARRA_UA_TYPE_STRING = 12,
DARRA_UA_TYPE_DATETIME = 13,
DARRA_UA_TYPE_GUID = 14,
DARRA_UA_TYPE_BYTESTRING = 15,
DARRA_UA_TYPE_XML_ELEMENT = 16,
DARRA_UA_TYPE_NODE_ID = 17,
DARRA_UA_TYPE_EXPANDED_NODE_ID = 18,
DARRA_UA_TYPE_STATUS_CODE = 19,
DARRA_UA_TYPE_QUALIFIED_NAME = 20,
DARRA_UA_TYPE_LOCALIZED_TEXT = 21,
DARRA_UA_TYPE_EXTENSION_OBJECT = 22,
DARRA_UA_TYPE_DATA_VALUE = 23,
DARRA_UA_TYPE_VARIANT = 24,
DARRA_UA_TYPE_DIAGNOSTIC_INFO = 25
} DarraUa_BuiltinType;

内存所有权

DarraUa_Variant* 是 opaque pointer, 由 Stack pool 管理:

来源释放
DarraUa_Variant_New()DarraUa_Variant_Delete(v)
DarraUa_Session_Call(...) 输出数组的每项DarraUa_VariantArray_Delete(arr, count) (一次性)
DarraUa_DataValue_GetValue(dv) 返回的 const DarraUa_Variant*不要释放 (生命周期 = dv)

DarraUa_Variant_GetString / _GetStringArrayItem 返回的 const char* 是 Variant 内部缓冲, 不要 free. 想保留请 strdup.


ToString (打印)

C 没有自动 ToString, 自己根据 type 打印:

static void print_variant(const DarraUa_Variant* v)
{
if (!v || DarraUa_Variant_GetType(v) == DARRA_UA_TYPE_NULL) {
printf("(null)"); return;
}
switch (DarraUa_Variant_GetType(v)) {
case DARRA_UA_TYPE_DOUBLE: {
double d = 0.0; DarraUa_Variant_GetDouble(v, &d);
printf("%g", d); break;
}
case DARRA_UA_TYPE_INT32: {
int32_t i = 0; DarraUa_Variant_GetInt32(v, &i);
printf("%d", (int)i); break;
}
case DARRA_UA_TYPE_STRING:
printf("\"%s\"", DarraUa_Variant_GetString(v)); break;
case DARRA_UA_TYPE_DATETIME:
printf("ft=%lld", (long long)DarraUa_Variant_GetDateTime(v)); break;
default:
printf("<type %d>", (int)DarraUa_Variant_GetType(v));
}
}

下一步