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) C's int
и Golang's int
могут иметь разные размеры, поэтому для этого требуется объявление cgo (C.int
) или ручное сопоставление сслучайный выбор (попробуйте также int32, int64, если вы не хотите использовать cgo)
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 (чтение данных, пока байт не завершится нулем, учитывая, что * байт указывает на первый элемент строки), но я предлагаю использовать уже реализованные функции времени выполнения:
//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)