diff --git a/ctypes/compile.sh b/ctypes/compile.sh new file mode 100644 index 0000000000000000000000000000000000000000..736d14689fcf31186110ae7aa2a0156014c506ef --- /dev/null +++ b/ctypes/compile.sh @@ -0,0 +1,2 @@ +# Compile a shared library +gcc -shared -o libmean.so.1 mean.c \ No newline at end of file diff --git a/ctypes/libmean.so.1 b/ctypes/libmean.so.1 new file mode 100755 index 0000000000000000000000000000000000000000..1ede0ce64eb59a8cf19dfffde096fbdf7fe4c32d Binary files /dev/null and b/ctypes/libmean.so.1 differ diff --git a/ctypes/main.py b/ctypes/main.py new file mode 100644 index 0000000000000000000000000000000000000000..d5549a5d439d8c34b7361c59bba04b606ea2e2fe --- /dev/null +++ b/ctypes/main.py @@ -0,0 +1,28 @@ +# https://solarianprogrammer.com/2019/07/18/python-using-c-cpp-libraries-ctypes/ +# https://gist.github.com/elyezer/7099291 + +# https://www.geeksforgeeks.org/turning-a-function-pointer-to-callable/ +# https://stackoverflow.com/questions/9420673/is-it-possible-to-compile-c-code-using-python +# https://documentation.help/Python-3.2.1/ctypes.html + +import ctypes +import os +import subprocess + +def buildLibrary(): + + # store the return code of the c program(return 0) + # and display the output + s = subprocess.check_call("bash compile.sh", shell=True) + print("return code:\n{}".format(s)) + +buildLibrary() + + +libmean = ctypes.CDLL("libmean.so.1") # loads the shared library +libmean.mean.restype = ctypes.c_double # define mean function return type +print(libmean.mean) +print(libmean.mean(ctypes.c_double(10), ctypes.c_double(3))) # call mean function needs cast arg types +libmean.mean.argtypes = [ctypes.c_double, ctypes.c_double] # define arguments types +print(libmean.mean(10, 3)) # call mean function does not need cast arg types +print(type(libmean.mean(10, 5))) \ No newline at end of file diff --git a/ctypes/mean.c b/ctypes/mean.c new file mode 100644 index 0000000000000000000000000000000000000000..12d80b0a402f33c1aea74f5697ecc49282a6231c --- /dev/null +++ b/ctypes/mean.c @@ -0,0 +1,5 @@ +#include "mean.h" + +double mean(double a, double b) { + return (a+b)/2; +} \ No newline at end of file diff --git a/ctypes/mean.h b/ctypes/mean.h new file mode 100644 index 0000000000000000000000000000000000000000..a52ef612da30d036480c0690f2ae20e944d3db23 --- /dev/null +++ b/ctypes/mean.h @@ -0,0 +1,3 @@ + +// Returns the mean of passed parameters +double mean(double, double); \ No newline at end of file diff --git a/python-c-api_solution/demomodule.c b/python-c-api_solution/demomodule.c index 1657aca00836095a00929dff4e20ec84eb65090f..d3236235dc632dc43677681bc678da35122728b0 100644 --- a/python-c-api_solution/demomodule.c +++ b/python-c-api_solution/demomodule.c @@ -32,6 +32,30 @@ static PyObject *DemoLib_MakeStr(PyObject *self, PyObject *args) { return Py_BuildValue("s", result); } + +static PyObject *DemoLib_AddNumberWithPointer(PyObject *self, PyObject *args) { + int *number_1; + int *number_2; + if (!PyArg_ParseTuple(args, "ii", &number_1, &number_2)) { + return NULL; + } + + int result; + int (*pf) (int, int); + pf = &add_number; + result = add_number_using_pointer(pf, number_1, number_2); + return Py_BuildValue("i", result); +} + + + + + + + + + + // module's function table static PyMethodDef DemoLib_FunctionsTable[] = { { @@ -39,16 +63,35 @@ static PyMethodDef DemoLib_FunctionsTable[] = { DemoLib_AddNumber, // C wrapper function METH_VARARGS, // received variable args (but really just 1) "adds two numbers" // documentation - }, { + }, + + + { + "add_number_with_pointer", // name exposed to Python + DemoLib_AddNumberWithPointer, // C wrapper function + METH_VARARGS, // received variable args (but really just 1) + "adds two numbers via a pointer function" // documentation + }, + + + { "make_str", // name exposed to Python DemoLib_MakeStr, // C wrapper function METH_VARARGS, // received variable args (but really just 1) "adds two strings" // documentation - }, { + }, + + + { NULL, NULL, 0, NULL } }; + + + + + // modules definition static struct PyModuleDef DemoLib_Module = { PyModuleDef_HEAD_INIT,