Provide a callback in Python code which expects a JSON string. Forward this to a GO dynamic library and make GO calling the Python callback with a JSON string
Python 3 and Go >= 1.18 required. Go module mode (go mod init ....)
import ctypes
# Define callback type for Python
CALLBACK_TYPE_JSON_STRING = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
def python_callback(jsonStr):
print(f"Python callback received: '{jsonStr.decode('utf-8')}'")
# Load Go library
golang_lib = ctypes.CDLL('./callback.so')
# Call a function in GO which immediately calls back
golang_lib.callme_with_json(CALLBACK_TYPE_JSON_STRING(python_callback))
package main
/*
#include <stdlib.h>
typedef void (*ptr_to_function_expecting_json_string) (char*);
static inline void call_c_func_with_json_str(ptr_to_function_expecting_json_string ptr, char* jsonStr) {
(ptr)(jsonStr);
}
*/
import "C"
import (
"fmt"
"unsafe"
)
//export callme_with_json
func callme_with_json(fn C.ptr_to_function_expecting_json_string) {
fmt.Println("Calling python callback with JSON string")
jsonStr := C.CString(`{"the_answer_is": 42}`)
defer C.free(unsafe.Pointer(jsonStr))
C.call_c_func_with_json_str(fn, jsonStr)
}
func main() {}
go build -o callback.so -buildmode=c-shared callback.go
python3 callback.py
The string should be copied in Python code for further processing, since the
Calling python callback with JSON string
Python callback received: '{"the_answer_is": 42}'
For further processing of the given JSON string it is most likely not such a bad idea to make an object from the string in the Python callback. Go will release he memory of the CString as soon as the callback is called and the Go function is left.
Note: Doesn't work if the Python callback is called from another goroutine.