Ich versuche, eine Routine in Go zu entwickeln, die von einem C++ - Programm aufgerufen wird. Die Go sieht wie folgt aus:Wie wird eine Zeichenfolge von JSON an einen C-Aufrufer (Golang CGO) zurückgegeben?
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() {}
Wenn ich für die Rückkehr k.Key Aussage alles etwas hart codierten Wert ersetzen funktioniert gut und die C oder C++ können die exportierte GetKey Funktion aufrufen. Wenn ich versuche, die decodierte JSON-Zeichenfolge von k.Key zurückzugeben oder nur die Zeichenfolge aus der Variablen mit dem Namen body zurückzugeben - erhalte ich einen Fehler:
Laufzeitfehler: cgo Ergebnis hat Go-Zeiger goroutine 17 [ausgeführt, gesperrt zu thread]
ich baue dies wie folgt:
-buildmode = c-Archiv example.go
Die C++ gebaut wird wie folgt bauen gehen:
g ++ -pthread test.cpp beispiel.a -o test
Was fehlt mir, damit das funktioniert, ohne einen Panikfehler zu verursachen? Ich suche nach einer Antwort, muss sie aber noch lösen.
@JimB & @Jsor, vielen Dank für Ihre Antworten. Die Rückkehr einer * C.char hat sicherlich funktioniert. Ich frage mich jedoch, wenn ich es als eine Go-Zeichenfolge hinter den Kulissen in der automatisch generierten Header-Datei Go erzeugt und übergibt eine C-Struktur mit dem Namen GoString, die ein Char-Array namens p und die Länge mit dem Namen n enthält. Solange ich eine hard-codierte Zeichenfolge anstelle von k.Key übergebe, funktioniert es tatsächlich und ich kann das automatisch erzeugte char-Array in C++ abfragen. Wenn ich versuche, k.Key zurückzugeben, wirft eine Zeichenkette diese Ausnahme. Ist es möglich, die Go-Zeichenfolge zu konvertieren oder eine Notation zur Export-Dekoration hinzuzufügen, damit sie funktioniert?
Ich kann das C.CString Char-Array sicherlich zurückgeben und es funktioniert - danke! Ich möchte nur verstehen, warum es funktioniert, wenn eine hart codierte Zeichenfolge zurückgegeben wird und nicht in dem Beispiel, das ich gepostet habe.
Vielen Dank für Ihre Zeit und Erklärungen.
(FYI, @ Erwähnungen funktionieren nur in Kommentaren) Sie können den GoString nicht sicher von C aus verwenden, da er einen Zeiger auf den in Go zugewiesenen Speicher enthält. Die Tatsache, dass ein String-Literal von cgocheck nicht erkannt wird, ist nebensächlich. – JimB
@ JimB, danke für den Tipp und die Erklärung. –