Я следил за этим
https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf
Теперь я делаю следующее: -
- Передайте строку Json
- Используйте Json Unmarshall со ссылкой на Go Struct и строку
- Do Business Logic & Operations
- Маршал структуры к JSON String
- Возвращение
Теперь проблема, с которой я сталкиваюсь, заключается в том, что я получаю исключение Out-of-Memory
при запуске его через python. Если я запускаю его через обычный Go, то он работает хорошо.
Также, если я не разбираю и просто инициализирую структуру нормально, у меня нет проблемы, и я получаю строку json обратно. Но мне нужно передать структурированные данные между ними.
Проблема возникает в линии Unmarshal
func BuildCRMLinkFromJSON(jsonstring string) CRMLinkBO {
var crmLink CRMLink = CRMLink{}
json.Unmarshal([]byte(jsonstring), &crmLink)
var clb = CRMLinkBO{crmLink: crmLink}
return clb
}
Ошибка времени выполнения:
runtime: out of memory: cannot allocate 140328041390080-byte block (66781184 in use)
fatal error: out of memory
или
Shauryas-MacBook-Pro:go-python-interfacing xuryax$ python pythonclient.py
unexpected fault address 0x210c1a334
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0x210c1a334 pc=0x1087b0c75]
Минимальное воспроизведение:
usego.go
package main
import (
"encoding/json"
"fmt"
)
import "C"
// Data Model
type CustomField struct {
Field string `json:"field"`
Value string `json:"value"`
}
type PersonDetails struct {
Person_id string `json:"person_id"`
Detail []CustomField `json:"detail"`
}
func New(pid string) PersonDetails {
var p = PersonDetails{"HARDCODED PID IN GO", []CustomField{}}
return p
}
func BuildFromJSON(jsonString string) PersonDetails {
var person_detail PersonDetails = PersonDetails{}
json.Unmarshal([]byte(jsonString), &person_detail)
return person_detail
}
func ConvertToJSON(p PersonDetails) string {
fmt.Println(p)
var je, _ = json.Marshal(p)
return string(je)
}
func AddValue(p PersonDetails) PersonDetails {
var CustField = CustomField{"Hardcoded Field in Go", "Hardcoded Value in Gos"}
p.Detail = append(p.Detail, CustField)
return p
}
//export DoJSONOperation
func DoJSONOperation(jsonString string) *C.char {
var p = BuildFromJSON(jsonString)
p = AddValue(p)
var nstr = ConvertToJSON(p)
return C.CString(nstr)
}
//export DoNormalOperation
func DoNormalOperation(jsonString string) *C.char {
var p = New(jsonString)
p = AddValue(p)
var nstr = ConvertToJSON(p)
fmt.Println("Before Return: ", string(nstr))
return C.CString(nstr)
}
func main() {
// DO noting
// var jsonStr = `{"person_id":"JsonID","detail":[{"field":"json passed field", "value":"json passed value"}]}`
}
PythonClient.py
from ctypes import *
import json
def main():
lib = cdll.LoadLibrary("/Users/xuryax/work/repos/research/go-python-interfacing/usego.so")
lib.DoJSONOperation.argtypes = [c_char_p]
lib.DoJSONOperation.restype = c_char_p
json_string = """{"person_id":"PythonJsonID","detail":[{"field":"json passed field", "value":"json passed value"}]}"""
normal_pid = "Python ID"
updated_json = lib.DoNormalOperation(normal_pid)
print(updated_json)
if __name__=="__main__":
main()
Странная вещь, которую я обнаружил, если я использую ту, что жестко закодирована, она возвращает указатель (целое число), но в моем предыдущем эксперименте я вернул строку.