Python C / C ++ Extension Pattern-Pointer

How to have a pointer on the C / C ++ side in Python.

Something wants to use a C ++ class from Python.

class Hello {
 public:
  void hello();
};

PyCapsule_New

Use PyCapsule_New to return a C / C ++ pointer asPyObject *.

static void py_hello_free(PyObject *obj);

static PyObject* py_hello_alloc(PyObject *self, PyObject *args)
{
  // Allocate a new C++ pointer h as a Python object "_Hello"
  Hello* const h= new Hello();
  
  return PyCapsule_New(h, "_Hello", py_hello_free);
}

If you pass a function that releases the pointer, Python will release it. If you manage the memory on the C / C ++ side and do not need to release it, you can pass NULL instead of py_hello_free.

void py_hello_free(PyObject *obj)
{
  // Destructor function for _Hello pointer, called automatically from Python
  Hello* const h= (Hello*) PyCapsule_GetPointer(obj, "_Hello");
    
  delete h;
}

PyCapsule_GetPointer

To return to a C / C ++ pointer PyCapsule_GetPointer:

PyObject* py_hello(PyObject *self, PyObject *args)
{
  // Use _Hello pointer from Python
  PyObject* py_obj;
  
  if(!PyArg_ParseTuple(args, "O", &py_obj))
    return NULL;

  Hello* h= (Hello*) PyCapsule_GetPointer(py_obj, "_Hello");
  if(h == 0) return NULL;

  h->hello();

  Py_RETURN_NONE;
}

The usual code that makes C / C ++ extensions

#include <cstdio>
#include "Python.h"

// ...Code above...

static PyMethodDef methods[] = {
  {"hello_alloc", py_hello_alloc, METH_VARARGS, "allocate a Hello object"},
  {"hello",       py_hello,       METH_VARARGS, "call hello() method"},
  {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
  PyModuleDef_HEAD_INIT,
  "cext02",              // name of this module
  "Use C/C++ pointer",  // Doc String
  -1,
  methods
};

PyMODINIT_FUNC
PyInit_cext02(void) {  
  return PyModule_Create(&module);
}

The usual setup.py

from distutils.core import setup, Extension

setup(name='cext02',
      version='0.0.1',
      description='c_ext02 pointer',
      author='Jun Koda',
      url='https://github.com/junkoda/python_c_ext',
      ext_modules=[
          Extension('cext02', ['cext02.cpp'])
      ]
)

compile

$ python3 setup.py build_ext --inplace

From python

import cext02  #Extension by C
h = cext02.hello_alloc() # h = new Hello()Something like
cext02.hello(h) # h->hello()Call

Use like. (Of course, if you wrap it in a Python class, you can use it like an object.)

reference

--Before you start extending C, you should read the Python Cookbook first. Python Cookbook 3rd Edition (O'Reilly)

Recommended Posts

Python C / C ++ Extension Pattern-Pointer
I tried Python C extension
python C ++ notes
python, openFrameworks (c ++)
Python C / C ++ Extension Pattern-Pass data to Python as np.array
Next Python in C
Computation drill python (extension)
C API in Python 3
ABC147 C --HonestOrUnkind2 [Python]
Extend python in C ++ (Boost.NumPy)
ABC163 C problem with python3
Python, Java, C ++ speed comparison
C / C ++ programmer challenges Python (class)
ABC memorandum [ABC163 C --managementr] (Python)
Binary search in Python / C ++
Multi-stage selection (C # / Python) (old)
Implement extension field in Python
Python started by C programmers
ABC188 C problem with python3
ABC187 C problem with python
Solve ABC163 A ~ C with Python
Call C from Python with DragonFFI
Multi-stage selection (Go / C # / Ruby / Python)
Python
ABC127 A, B, C Explanation (python)
Try implementing extension method in python
ABC166 in Python A ~ C problem
Call popcount from Ruby / Python / C #
Introduction to Protobuf-c (C language ⇔ Python)
Python cheat sheet (for C ++ experienced)
Solve ABC168 A ~ C with Python
ABC memorandum [ABC161 C --Replacing Integer] (Python)
Solve ABC036 A ~ C in Python
Tips for calling Python from C
Execute Python code from C # GUI
How to wrap C in Python
ABC memorandum [ABC158 C --Tax Increase] (Python)
Solved AtCoder ABC 114 C-755 with Python3
C / C ++ programmer challenges Python (first step)
Solve ABC162 A ~ C with Python
Run Python scripts synchronously from C #
Solve ABC167 A ~ C with Python
ABC128 A, B, C commentary (python)
Solve ABC158 A ~ C with Python
ABC126 A, B, C Explanation (python)
Solve ABC037 A ~ C in Python
Write C unit tests in Python
AtCoder Beginner Contest 174 C Problem (Python)
Call C / C ++ from Python on Mac
Call c language from python (python.h)
Solve ABC175 A, B, C in Python
Execute Python code on C ++ (using Boost.Python)
Python 2.7, 3.4, 3.5 extension module build environment on Windows
Closure 4 language comparison (Python, JavaScript, Java, C ++)
Algorithm in Python (ABC 146 C Binary Search
Implement FIR filters in Python and C
[C] [python] Read with AquesTalk on Linux
python> keyword arguments> hoge (** {'a': 1,'b': 2,'c': 3})
Write O_SYNC file in C and Python
Enumerate duplicate combinations (C ++) → Add Python code
VScode environment construction (Windows10, Python, C ++, C, Git)