Недостаточно памяти при использовании метода Голанга в Python - PullRequest
1 голос
/ 20 апреля 2019

Я следил за этим 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()

Странная вещь, которую я обнаружил, если я использую ту, что жестко закодирована, она возвращает указатель (целое число), но в моем предыдущем эксперименте я вернул строку.

1 Ответ

0 голосов
/ 20 апреля 2019

Ответ кажется довольно простым на самом деле. Это проблема с типизацией, которую я пропустил.

Метод должен принимать *C.char

//export DoJSONOperation
func DoJSONOperation(jsonString *C.char) *C.char {
    var GoString = C.GoString(jsonString)
    var p = BuildFromJSON(GoString)
    p = AddValue(p)
    var nstr = ConvertToJSON(p)
    return C.CString(nstr)
}

И, похоже, это решает проблему.

В Python нам также нужно набирать текст. И вместо отправки Python String нам нужно отправить. c_char_p(jsonString)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...