1 回答
TA贡献1828条经验 获得超3个赞
1)我怀疑这cost char*是否意味着UTF16编码。所以你所需要的只是获取原始数据:
sensigrafo := "en\000" // \000 = 0 = null termination, \0 does not valid
options := "\000"
...
uintptr(*(*unsafe.Pointer)(unsafe.Pointer(&sensigrafo))
uintptr(*(*unsafe.Pointer)(unsafe.Pointer(&options))
// *(*unsafe.Pointer) are accessing the first field of string header:
type string struct {
data *byte
len int
}
// same with slices
// but for them there's less ugly way:
sensigrafo := []byte("en\000")
options := []byte("\000")
uintptr(unsafe.Pointer(&sensigrafo[0]))
uintptr(unsafe.Pointer(&options[0]))
2) Cint和 Golangint可能有不同的 sizeof,所以这需要 cgo 声明 ( C.int) 或手动匹配随机选择(如果你不想使用 cgo,也可以尝试 int32、int64)
type senseiErr struct {
code C.int /* Golang's int32/int64 */
error_string *byte // pointer types are same as C's void* or Golang's unsafe.Pointer
}
错误的偏移量可能会导致 error_string 为空或指向随机地址。
3)要读取内容,您必须使用与 C 相同的方法(读取数据直到 null 终止字节,考虑到 *byte 指向字符串的第一个元素),但我建议使用已经实现的运行时函数:
//go:linkname gostringn runtime.gostringn
func gostringn(p *byte, l int) string
//go:linkname findnull runtime.findnull
//go:nosplit
func findnull(s *byte) int
...
error_string := gostringn(err.error_string, findnull(err.error_string))
// or cgo one:
type senseiErr struct {
code C.int
error_string *C.char
}
...
error_string := C.GoString(err.error_string)
- 1 回答
- 0 关注
- 108 浏览
添加回答
举报