diff --git a/python_pycapsule_test/build/lib.linux-x86_64-3.6/demo.cpython-36m-x86_64-linux-gnu.so b/python_pycapsule_test/build/lib.linux-x86_64-3.6/demo.cpython-36m-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..27b58462f3254677f79e2b1c1d144d0cdf1ed634 Binary files /dev/null and b/python_pycapsule_test/build/lib.linux-x86_64-3.6/demo.cpython-36m-x86_64-linux-gnu.so differ diff --git a/python_pycapsule_test/demo.egg-info/PKG-INFO b/python_pycapsule_test/demo.egg-info/PKG-INFO new file mode 100644 index 0000000000000000000000000000000000000000..bb988b6a17bcf961cdb2986a24431294f975c84a --- /dev/null +++ b/python_pycapsule_test/demo.egg-info/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: demo +Version: 1.0 +Summary: Python wrapper for custom C extension +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/python_pycapsule_test/demo.egg-info/SOURCES.txt b/python_pycapsule_test/demo.egg-info/SOURCES.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a14b9e5fee1361c16505c7a29de8f263563903c --- /dev/null +++ b/python_pycapsule_test/demo.egg-info/SOURCES.txt @@ -0,0 +1,6 @@ +demomodule.c +setup.py +demo.egg-info/PKG-INFO +demo.egg-info/SOURCES.txt +demo.egg-info/dependency_links.txt +demo.egg-info/top_level.txt \ No newline at end of file diff --git a/python_pycapsule_test/demo.egg-info/dependency_links.txt b/python_pycapsule_test/demo.egg-info/dependency_links.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/python_pycapsule_test/demo.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/python_pycapsule_test/demo.egg-info/top_level.txt b/python_pycapsule_test/demo.egg-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..1549b67ca5936e6893c89221d508697e7e97d42b --- /dev/null +++ b/python_pycapsule_test/demo.egg-info/top_level.txt @@ -0,0 +1 @@ +demo diff --git a/python_pycapsule_test/demolib.h b/python_pycapsule_test/demolib.h new file mode 100644 index 0000000000000000000000000000000000000000..340c9166a09a86eedede926f6bd0403be9c0e38a --- /dev/null +++ b/python_pycapsule_test/demolib.h @@ -0,0 +1,6 @@ +// Example header file +// int add_number(int number_1, int number_2); +// char* make_str(const char *s1, const char *s2); +// int add_number_using_pointer(int (*pf)(int, int), int number_1, int number_2); +// int multiply_number(int number_1, int number_2); +void capsule_cleanup(PyObject *capsule); \ No newline at end of file diff --git a/python_pycapsule_test/demomodule.c b/python_pycapsule_test/demomodule.c new file mode 100644 index 0000000000000000000000000000000000000000..adcb1ff86ce818e7d2871c0d375bdeb662ca6b22 --- /dev/null +++ b/python_pycapsule_test/demomodule.c @@ -0,0 +1,143 @@ +// demomodule.c +#include <Python.h> +#include "demolib.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +// void capsule_cleanup(PyObject *capsule) { +// double *content_capsule; +// if (!(content_capsule = (double*) PyCapsule_GetPointer(capsule, "DOUBLE"))) +// return NULL; + +// // Free stuff +// printf("Via other function: Before deleting: Pointer %p and value %f\n", content_capsule, *content_capsule); +// PyMem_Free(content_capsule); +// printf("Via other function: After deleting: Pointer %p and value %f\n", content_capsule, *content_capsule); + +// // Use your specific gc implementation in place of free if you have to +// free(content_capsule); +// } + +// https://stackoverflow.com/questions/51505391/how-to-parse-void-to-pyobject + +typedef struct { + int book_id; +} Books; + + +//////////////////////// +static PyObject *free_content_capsule(PyObject *self, PyObject *args) +{ + PyObject *pycapsule = NULL; + if (!PyArg_ParseTuple(args, "O", &pycapsule)) + return NULL; + + // double *content_capsule; + // if (!(content_capsule = (double*) PyCapsule_GetPointer(pycapsule, "DOUBLE"))) + // return NULL; + Books *content_capsule; + if (!(content_capsule = (Books*) PyCapsule_GetPointer(pycapsule, "BOOKS"))) + return NULL; + + PyMem_Free(content_capsule); + // free(content_capsule); + + return Py_BuildValue(""); +} + +static PyObject *print_content_capsule(PyObject *self, PyObject *args) +{ + PyObject *pycapsule = NULL; + if (!PyArg_ParseTuple(args, "O", &pycapsule)) + return NULL; + + Books *content_capsule; + if (!(content_capsule = (Books*) PyCapsule_GetPointer(pycapsule, "BOOKS"))) + return NULL; + + printf("Pointer %p and value %d\n", content_capsule, content_capsule->book_id); + + return Py_BuildValue(""); +} + +Books *create_book_pointer(void); +Books *create_book_pointer(void) +{ + Books *content_capsule = (Books *)malloc(sizeof(Books *)); + if (NULL == content_capsule) + return NULL; + + content_capsule->book_id = 6.0; + return content_capsule; +} + +double * create_double_pointer(void); +double * create_double_pointer(void) +{ + double *content_capsule = (double *) malloc(sizeof(double *)); + if (NULL == content_capsule) + return NULL; + *content_capsule = 6.0; + + return content_capsule; +} + +static PyObject *create_capsule(PyObject *self, PyObject *args) +{ + // double *content_capsule = create_double_pointer(); + Books *content_capsule = create_book_pointer(); + + // printf("Pointer %p and value %d\n", content_capsule, *content_capsule; + printf("Pointer %p and value %d\n", content_capsule, content_capsule->book_id); + + // PyObject * ret = PyCapsule_New(content_capsule, "DOUBLE", NULL); + PyObject * ret = PyCapsule_New(content_capsule, "BOOKS", NULL); + return ret; +} + + +/////////////////////////////////////////////////////////////////////////////////// +// module's function table +static PyMethodDef DemoLib_FunctionsTable[] = { + // Capsule items + { + "create_capsule", // name exposed to Python + create_capsule, // C wrapper function + METH_VARARGS, // received variable args (but really just 1) + "Create capsule object" // documentation + }, + + { + "print_content_capsule", // name exposed to Python + print_content_capsule, // C wrapper function + METH_VARARGS, // received variable args (but really just 1) + "Opens the capsule and prints content" // documentation + }, + + { + "free_content_capsule", // name exposed to Python + free_content_capsule, // C wrapper function + METH_VARARGS, // received variable args (but really just 1) + "Free the capsule memory" // documentation + }, + + + { + NULL, NULL, 0, NULL + } +}; + +/////////////////////////////////////////////////////////////////////////////////// +// modules definition +static struct PyModuleDef DemoLib_Module = { + PyModuleDef_HEAD_INIT, + "demo", // name of module exposed to Python + "Demo Python wrapper for custom C extension library.", // module documentation + -1, + DemoLib_FunctionsTable +}; + +PyMODINIT_FUNC PyInit_demo(void) { + return PyModule_Create(&DemoLib_Module); +} \ No newline at end of file diff --git a/python_pycapsule_test/dist/demo-1.0-py3.6-linux-x86_64.egg b/python_pycapsule_test/dist/demo-1.0-py3.6-linux-x86_64.egg new file mode 100644 index 0000000000000000000000000000000000000000..ee497d2b179ca909da9a9819075183e1a914c9c3 Binary files /dev/null and b/python_pycapsule_test/dist/demo-1.0-py3.6-linux-x86_64.egg differ diff --git a/python_pycapsule_test/main.py b/python_pycapsule_test/main.py new file mode 100644 index 0000000000000000000000000000000000000000..687d37a542094f9a39638c11de72c56e67631a9f --- /dev/null +++ b/python_pycapsule_test/main.py @@ -0,0 +1,21 @@ +import demo +import time + +def is_capsule(o): + t = type(o) + return t.__module__ == 'builtins' and t.__name__ == 'PyCapsule' + +# Make capsule +caps = demo.create_capsule() + +print(dir(caps)) + +# Print content (twice, just to see if it persists) +demo.print_content_capsule(caps) +demo.print_content_capsule(caps) + +demo.free_content_capsule(caps) # Free it +demo.print_content_capsule(caps) + +del caps + diff --git a/python_pycapsule_test/setup.py b/python_pycapsule_test/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..1c180817e42524241d3a8e55e1ee717cf907a7ec --- /dev/null +++ b/python_pycapsule_test/setup.py @@ -0,0 +1,12 @@ +from setuptools import Extension, setup + + + +module = Extension("demo", + sources=[ + 'demomodule.c' + ]) +setup(name='demo', + version='1.0', + description='Python wrapper for custom C extension', + ext_modules=[module]) \ No newline at end of file