py_.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package api
  2. // Here we define Python wrappers in C for our "go_" functions
  3. // They handle the conversion between Python and C types
  4. // We are demonstrating the two supported Python ABIs:
  5. // 1) the more common PyCFunction ABI, which passes arguments as Python tuples and dicts, and
  6. // 2) the newer _PyCFunctionFast ABI, which passes arguments as a more efficient stack
  7. // Unfortunately we must use C and not Go because:
  8. // 1) the "PyArg_Parse_" functions all use variadic arguments, which are not supported by cgo, and
  9. // 2) the "PyArg_Parse_" functions unpack arguments to pointers, which we cannot implement in Go
  10. // Note: cgo exports cannot be in the same file as cgo preamble functions,
  11. // which is why this file cannot be combined with "go_.go"
  12. // and is also why must forward-declare the "go_" functions in the cgo preamble
  13. // See:
  14. // https://docs.python.org/3/c-api/arg.html
  15. /*
  16. #cgo pkg-config: python3-embed
  17. #define PY_SSIZE_T_CLEAN
  18. #include <Python.h>
  19. void go_api_sayGoodbye();
  20. char *go_api_concat(char*, char*);
  21. // PyCFunction signature
  22. PyObject *py_api_sayGoodbye(PyObject *self, PyObject *unused) {
  23. go_api_sayGoodbye();
  24. return Py_None;
  25. }
  26. // PyCFunction signature
  27. PyObject *py_api_concat(PyObject *self, PyObject *args) {
  28. char *arg1 = NULL, *arg2 = NULL;
  29. PyArg_ParseTuple(args, "ss", &arg1, &arg2);
  30. char *r = go_api_concat(arg1, arg2);
  31. return PyUnicode_FromString(r);
  32. }
  33. // _PyCFunctionFast signature
  34. PyObject *py_api_concat_fast(PyObject *self, PyObject **args, Py_ssize_t nargs) {
  35. char *arg1 = NULL, *arg2 = NULL;
  36. _PyArg_ParseStack(args, nargs, "ss", &arg1, &arg2);
  37. char *r = go_api_concat(arg1, arg2);
  38. return PyUnicode_FromString(r);
  39. }
  40. */
  41. import "C"