Я пытаюсь разработать рутину в Go, которая будет вызываться программой C++. Go выглядит следующим образом:Как вернуть строку из JSON в C-call (Golang CGO)?
package main
import (
"C"
"encoding/json"
"log"
)
type keydata struct {
Key string `json:"key"`
Error string `json:"Error"`
}
func lookupKey() string {
//simplified to remove the call to web service
body := "{\"key\": \"blahblah\", \"Error\": \"\"}"
k := keydata{}
err := json.Unmarshal([]byte(body), &k)
if err != nil {
log.Fatal(err)
}
return k.Key
}
//export GetKey
func GetKey() string {
theKey := lookupKey()
return theKey
}
func main() {}
Если я заменяю некоторые трудно закодированное значение для возвращения заявления k.Key все работает отлично и C или C++ может вызвать экспортируемую функцию GETKEY. Когда я пытаюсь вернуть декодированную строку JSON из k.Key или даже просто вернуть строку из переменной с именем body - я получаю сообщение об ошибке:
Ошибка выполнения: cgo result имеет указатель Go goroutine 17 [работает, заблокирован нить]
Я строю это следующим образом:
идут строить -buildmode = C-архив example.go
C++ построен следующим образом:
г ++ -pthread test.cpp example.a -o test
Что мне не хватает, чтобы сделать эту работу без повышения панической ошибки? Я копаю, чтобы найти ответ, но еще не решил это.
@JimB & @ Joror, большое вам спасибо за ваши ответы. Возвращение * C.char, безусловно, сработало. Мне все еще интересно, когда я возвращаю его как строку Go за кулисами в автоматически сгенерированный заголовочный файл Go фактически создает и передает структуру C с именем GoString, которая содержит массив символов с именем p и длиной n. Пока я передаю строчную кодировку вместо k.Key, она действительно работает, и я могу опросить автоматически сгенерированный массив символов в C++. Когда я пытаюсь вернуть k.Key, строка выдает это исключение. Можно ли использовать строку Go или добавить некоторые примечания к украшению экспорта, чтобы заставить его работать?
Я могу, конечно, вернуть массив символов C.CString и заставить его работать - спасибо! Я просто хочу понять, почему он работает при возврате строчной кодированной строки, а не в примере, который я опубликовал.
Благодарим вас за ваше время и объяснения.
(FYI, @ упоминает работать только в комментариях) Вы не можете использовать GoString безопасно от C, поскольку она содержит указатель на память, выделенную в Go. Тот факт, что использование строкового литерала пропущен cgocheck, находится рядом с точкой. – JimB
@JimB, спасибо за подсказку и объяснение. –