Documentation
¶
Overview ¶
Package cgo 提供与 C/C++ 代码交互相关的安全包装函数。
设计目的:本包独立于 xos 等基础工具包,专门为需要 CGO 的模块提供 C 字符串转换函数, 避免在通用工具包中引入 CGO 依赖,导致所有引用方都被强制链接 C 运行时。
同时,本包针对 caller 业务模块的 C 接口(PluginWrapCaller.h)提供跨 cgo 翻译单元的桥接函数(BridgeInitializeCaller / BridgeSetLogger):
- 集中处理 patchtools/cgo 翻译单元与 caller 业务翻译单元之间的 *_Ctype_char 转换
- 集中使用 unsafe.Pointer 中转(Go 语言层面无法避免,见 issue #13467)
- caller 业务代码无需关心跨翻译单元类型转换,caller.go 中无 unsafe 类型转换。
Index ¶
- func BridgeByteArrayToCString(ba []byte) unsafe.Pointer
- func BridgeDecodeProcCallerResult(cTempUnsafe unsafe.Pointer, allowEmpty bool, maxBodySize uint32) (body []byte, bodySize uint32, ok bool)
- func BridgeFreeMem(p unsafe.Pointer)
- func BridgeGoString(p unsafe.Pointer) string
- func BridgeInitializeCaller(caller unsafe.Pointer, pluginPath, configPath string) bool
- func BridgeProcCaller(caller unsafe.Pointer, body []byte, traceID []byte, commandID uint64, ...) unsafe.Pointer
- func BridgeSetLogger(caller unsafe.Pointer, logPath, appName string)
- func ByteArrayToSafeCString(ba []byte) *C.char
- func FreeCString(ptr *C.char)
- func FreeCStringPointer(ptr unsafe.Pointer)
- func GoStringToSafeCString(s string) *C.char
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BridgeByteArrayToCString ¶ added in v0.0.25
BridgeByteArrayToCString 是 caller 业务代码调用 ByteArrayToCString 的入口。
集中处理跨 cgo 翻译单元类型转换:patchtools/cgo.ByteArrayToSafeCString 返回 patchtools/cgo 翻译单元的 *_Ctype_char(Go 类型系统里与 caller.go 的 *C.char 是不同类型),caller 业务代码如直接 `(*C.char)(cstr)` 会触发跨翻译单元 unsafe 转换。本函数封装此转换,caller 业务代码改用 unsafe.Pointer。
返回的 unsafe.Pointer 可在 caller 翻译单元里安全转为 (*C.char), 转换操作请集中到 caller 侧唯一的 *_Ctype_char -> *C.char 桥接点。
注:caller 业务代码目前已通过 BridgeProcCaller 整体封装 procCaller 调用, 此函数保留以备将来其他 cgo 集成场景使用。
func BridgeDecodeProcCallerResult ¶ added in v0.0.25
func BridgeDecodeProcCallerResult(cTempUnsafe unsafe.Pointer, allowEmpty bool, maxBodySize uint32) (body []byte, bodySize uint32, ok bool)
BridgeDecodeProcCallerResult 从 C.procCaller 返回的 char* 缓冲中解码响应体。
C.procCaller 在 cTemp 指向的 C 堆缓冲区中存放以下结构(小端):
[ 0.. 4) bodySize uint32 - 后续响应体字节数 [ 4.. 4+bodySize ) body - 实际响应体
解码逻辑中所有 unsafe.Pointer 操作(cTemp -> unsafe.Pointer、跨平台指针 算术 bodySize 字段偏移、C.GoBytes 读取)都集中在本函数内,避免 caller 业务代码直接操作 unsafe 内存。
参数 cTempUnsafe 是 C.procCaller 在 caller 翻译单元返回的 *C.char, 通过 unsafe.Pointer 中转传入(cgo 跨翻译单元隔离约束:不同翻译单元的 *_Ctype_char 在 Go 类型系统里是不同类型,见 issue #13467)。函数体内 将其转换为 patchtools/cgo 翻译单元的 *_Ctype_char 后再读前缀字段。
allowEmpty 表示 bodySize == 0 是否合法:caller 处理空白瓦片场景时(HTTP Header 中包含 X-Tile-Empty=true)允许 bodySize == 0;其他场景必须 > 0。
maxBodySize 是允许的最大响应体字节数,避免恶意或损坏数据导致 C.GoBytes 一次性分配超大内存。
返回值:
- bodySize:cTemp 缓冲中前缀字段声明的响应体字节数(用于错误日志)。
- ok=false:响应体大小不合法(bodySize == 0 且 !allowEmpty,或 bodySize 超过上限), body 为 nil。caller 应自行调用 C.freeMem 释放 C++ 内存。
- ok=true:body 为解码后的响应体字节切片,caller 仍需自行释放 cTemp。
func BridgeFreeMem ¶ added in v0.0.25
BridgeFreeMem 是 C.freeMem 的封装,集中处理跨 cgo 翻译单元 *C.char -> unsafe.Pointer 中转。
func BridgeGoString ¶ added in v0.0.25
BridgeGoString 是 C.GoString 的封装,集中处理跨 cgo 翻译单元 *C.char -> Go string。
func BridgeInitializeCaller ¶ added in v0.0.24
BridgeInitializeCaller 透传到 C.initializeCaller。
把 patchtools/cgo 翻译单元的 *_Ctype_char 与 caller 自身 cgo 翻译单元的 *_Ctype_char 之间的转换集中在本函数体内(unsafe.Pointer 中转), caller.go 业务代码无需关心。
pluginPath / configPath 由 caller.go 传入 Go string,由本函数负责:
- 用 GoStringToSafeCString 把 Go string 转为 *_Ctype_char
- 集中做 unsafe.Pointer 中转,转为 caller 翻译单元的 *C.char
- 调用 C.initializeCaller
- 用 FreeCStringPointer 释放内存
返回 true 表示初始化成功,false 表示失败。
func BridgeProcCaller ¶ added in v0.0.25
func BridgeProcCaller(caller unsafe.Pointer, body []byte, traceID []byte, commandID uint64, cDataTypeOut, cHttpHeaderOut unsafe.Pointer) unsafe.Pointer
BridgeProcCaller 是 C.procCaller 的完整封装,集中处理跨 cgo 翻译单元的所有 unsafe.Pointer 操作。
集中执行:
- []byte -> *_Ctype_char 零拷贝转换(body / traceID)
- cgo 跨翻译单元 *_Ctype_char -> caller 翻译单元 *C.char 中转
- cgo 跨翻译单元 *_Ctype_uchar / *_Ctype_char_star 出参中转
caller 业务代码完全不出现 unsafe 转换。
参数:
- caller:plugin caller 指针(caller 翻译单元 void*,已转 unsafe.Pointer)
- body / traceID:null-terminated []byte 输入
- commandID:命令 ID
- cDataTypeOut:caller 翻译单元 *C.uchar 输出的 unsafe.Pointer 形式 (caller 业务代码传 unsafe.Pointer(&cDataType))
- cHttpHeaderOut:caller 翻译单元 **C.char 输出的 unsafe.Pointer 形式 (caller 业务代码传 unsafe.Pointer(&cHttpHeader))
返回值:C.procCaller 返回的 char* 缓冲(caller 翻译单元的 *C.char 转 unsafe.Pointer)
func BridgeSetLogger ¶ added in v0.0.24
BridgeSetLogger 透传到 C.setLogger,集中处理跨 cgo 翻译单元的 *_Ctype_char 类型转换。caller.go 业务代码不出现 unsafe 类型转换。
func ByteArrayToSafeCString ¶ added in v0.0.25
ByteArrayToSafeCString 是零拷贝 []byte -> *_Ctype_char 转换。
调用方必须确保:
- ba 已经以 null 结尾(最后一个字节 == 0)
- 在 C 函数调用期间 ba 保持存活(防止 GC 释放底层数组)
- 适用于同步 C 函数调用(C 函数不保存指针)
返回的 *_Ctype_char 是 patchtools/cgo 翻译单元的 *_Ctype_char,调用方 跨翻译单元使用须经 BridgeByteArrayToCString 桥接。
func FreeCStringPointer ¶
FreeCStringPointer 释放由 C.CString 分配的 C 字符串指针。 接受 unsafe.Pointer 类型参数。
func GoStringToSafeCString ¶
GoStringToSafeCString 是 C.CString 的安全包装, 用于消除静态扫描工具对 C.CString 的误报。 实际行为与 C.CString 一致(按字符串长度分配,无溢出风险)。
使用完毕后必须调用 FreeCString 释放内存,避免泄漏。
Types ¶
This section is empty.