diff --git a/ctypes_and_api/__pycache__/functions.cpython-36.pyc b/ctypes_and_api/__pycache__/functions.cpython-36.pyc index 5427d3f43ca347265356eea27b4a32d18b28153d..39e4e0bd6bcb1d9f2feb55439462d01ca74f9f3e 100644 Binary files a/ctypes_and_api/__pycache__/functions.cpython-36.pyc and b/ctypes_and_api/__pycache__/functions.cpython-36.pyc differ diff --git a/ctypes_and_api/demolib.c b/ctypes_and_api/demolib.c index 0d4af8cdadbdde4274d11f76ee9f54e44b10a7c9..1466aeb8a8a805493759d6432f9096f42d420c9c 100644 --- a/ctypes_and_api/demolib.c +++ b/ctypes_and_api/demolib.c @@ -1,36 +1,23 @@ #include <stdio.h> -#include <string.h> #include <stdlib.h> #include "demolib.h" - typedef double (*fn_def)(double, double); -int add_number_using_pointer(int (*pf)(int, int), int number_1, int number_2) { - int result; - result = pf(number_1, number_2); - return result; -} - -double calc_mean_using_pointer(long int str_1, double number_1, double number_2) +double run_function_via_pointer(long int str_1, double number_1, double number_2) { - printf("test for running function with mem addr %ld with arguments %f %f\n", str_1, number_1, number_2); - + // Function that recieves a long int containing the memory adress of a function, and two values + // the long int will be interpreted as a pointer, and the two values will be passed to this function + // will work as long as the function of which the memory adress is given accepts two doubles and returns a double + // convert into pointer fn_def fnptr = (fn_def)str_1; - printf("size of function pointer %zu\n",sizeof(fnptr)); - printf("%p size: %zu\n", fnptr, sizeof(fnptr)); - - double result; - result = fnptr(number_1, number_2); + // print some stuff + // printf("test for running function with mem addr %ld with arguments %f %f\n", str_1, number_1, number_2); + // printf("size of function pointer %zu\n",sizeof(fnptr)); + // printf("%p size: %zu\n", fnptr, sizeof(fnptr)); + double result = fnptr(number_1, number_2); return result; -} - -double test_func(char* str_1, double number_1, double number_2) { - // double result; - // result = pf(number_1, number_2); - printf("test for running function with mem addr %s with arguments %f %f\n", str_1, number_1, number_2); - return 6.5; } \ No newline at end of file diff --git a/ctypes_and_api/demolib.h b/ctypes_and_api/demolib.h index 805906094a1200689875a33eb4eadfdd024b7c07..454ab2db0c3343540204f7b49e8268b2975af4a8 100644 --- a/ctypes_and_api/demolib.h +++ b/ctypes_and_api/demolib.h @@ -1,5 +1 @@ -// Example header file - -// char construct_string(int number); -double calc_mean_using_pointer(long int str_1, double number_1, double number_2); -double test_func(char* str_1, double number_1, double number_2); \ No newline at end of file +double run_function_via_pointer(long int str_1, double number_1, double number_2); \ No newline at end of file diff --git a/ctypes_and_api/demomodule.c b/ctypes_and_api/demomodule.c index 90914d6be20aca37b7a7b1685c4af09d238a3783..91dcaa89765d5cec6d4f3adfffe3ec8127a2a155 100644 --- a/ctypes_and_api/demomodule.c +++ b/ctypes_and_api/demomodule.c @@ -2,48 +2,26 @@ #include <Python.h> #include "demolib.h" - -// https://stackoverflow.com/questions/51505391/how-to-parse-void-to-pyobject - -static PyObject *DemoLib_CalcMeanWithPointerTest(PyObject *self, PyObject *args) { - char *str_1; - double number_1; - double number_2; - if (!PyArg_ParseTuple(args, "sdd", &str_1, &number_1, &number_2)) { - return NULL; - } - - double result; - result = test_func(str_1, number_1, number_2); - return Py_BuildValue("d", result); -} - - -static PyObject *DemoLib_CalcMeanWithPointer(PyObject *self, PyObject *args) { +// Declare the function wrapping the python call and the c function +static PyObject *DemoLib_RunFunctionViaPointer(PyObject *self, PyObject *args) { long int str_1; double number_1; double number_2; if (!PyArg_ParseTuple(args, "ldd", &str_1, &number_1, &number_2)) { return NULL; } + // printf("%p contents %ld\n", &str_1, str_1); double result; - printf("%p contents %ld\n", &str_1, str_1); - result = calc_mean_using_pointer(str_1, number_1, number_2); + result = run_function_via_pointer(str_1, number_1, number_2); return Py_BuildValue("d", result); } // module's function table static PyMethodDef DemoLib_FunctionsTable[] = { { - "calc_mean_with_pointer", // name exposed to Python - DemoLib_CalcMeanWithPointer, // C wrapper function - METH_VARARGS, // received variable args (but really just 1) - "Calculate the mean of two values via a pointer function" // documentation - }, - { - "calc_mean_with_pointer_test", // name exposed to Python - DemoLib_CalcMeanWithPointerTest, // C wrapper function + "run_function_via_pointer", // name exposed to Python + DemoLib_RunFunctionViaPointer, // C wrapper function METH_VARARGS, // received variable args (but really just 1) "Calculate the mean of two values via a pointer function" // documentation }, diff --git a/ctypes_and_api/libmean.so.1 b/ctypes_and_api/libmean.so.1 index df6280d836c719bec47c764d75c8a0222edbf955..30b3abef76357932505c706ed356212859736b52 100755 Binary files a/ctypes_and_api/libmean.so.1 and b/ctypes_and_api/libmean.so.1 differ diff --git a/ctypes_and_api/main.py b/ctypes_and_api/main.py index b3af562518c0d270a3de9f338d017a3227904e0d..4a13c6b1852b00273e20f955f45a06a6b5554c79 100644 --- a/ctypes_and_api/main.py +++ b/ctypes_and_api/main.py @@ -1,22 +1,34 @@ import ctypes import os import subprocess - -from functions import loadLibraryFunction, buildLibrary - -import demo +import demo # load library with the C-interfacing +from functions import loadLibraryFunction, buildLibrary +# Build shared library buildLibrary() -# Loading library +# Loading shared library libmean = ctypes.CDLL("libmean.so.1") # loads the shared library # Get memory adress of function. mimicking a pointer -mem = ctypes.cast(libmean.mean, ctypes.c_void_p).value -print("mem adress of mean function {}, type: {}".format(mem, type(mem))) +mem_mean_function = ctypes.cast(libmean.mean, ctypes.c_void_p).value +print("mem adress of mean function {}, type: {}".format(mem_mean_function, type(mem_mean_function))) + +mem_product_function = ctypes.cast(libmean.product, ctypes.c_void_p).value +print("mem adress of product function {}, type: {}".format(mem_product_function, type(mem_product_function))) + +mem_sum_function = ctypes.cast(libmean.sum, ctypes.c_void_p).value +print("mem adress of sum function {}, type: {}".format(mem_sum_function, type(mem_sum_function))) + +print('\n\n') + +result_mean = demo.run_function_via_pointer(mem_mean_function, 10, 2.0) +print("Result of mean: {}\n".format(result_mean)) +result_product = demo.run_function_via_pointer(mem_product_function, 10, 2.0) +print("Result of product: {}\n".format(result_product)) -dong = demo.calc_mean_with_pointer(mem, 1.0, 2.0) -print(dong) \ No newline at end of file +result_sum = demo.run_function_via_pointer(mem_sum_function, 10, 2.0) +print("Result of sum: {}\n".format(result_sum)) diff --git a/ctypes_and_api/mean.c b/ctypes_and_api/mean.c index c8c1d178dccd4a52dad90f49137e32ef80f117b9..0810fe8cf6fe4abcc92f79b446d24132c80eacc7 100644 --- a/ctypes_and_api/mean.c +++ b/ctypes_and_api/mean.c @@ -3,18 +3,23 @@ #include <stdlib.h> #include <math.h> -double mean(double a, double b) { - printf("calculating mean with %f and %f", a, b); - return (a+b)/2; +double mean(double a, double b) +{ + printf("calculating mean of %f and %f\n", a, b); + double mean = (a+b)/2.0; + return mean; } -void print_pointer_to_mean() { - printf("pointer to mean function (via c code): %p\n", &mean); +double product(double a, double b) +{ + printf("Calculating product of %f and %f\n", a, b); + double product = a * b; + return product; } -double calc_mean_using_pointer(double (*pf)(double, double), double number_1, double number_2) { - double result; - result = pf(number_1, number_2); - printf("result running mean function with pointer to the function: %f", result); - return result; +double sum(double a, double b) +{ + printf("Calculating sum of %f and %f\n", a, b); + double sum = a + b; + return sum; } \ No newline at end of file diff --git a/ctypes_and_api/mean.h b/ctypes_and_api/mean.h index 035946d9a0b19f0b67490d28bce7eabf94a4a9b9..c79b11774bc61e3cd61c277f20aeecc694c49c5a 100644 --- a/ctypes_and_api/mean.h +++ b/ctypes_and_api/mean.h @@ -1,4 +1,3 @@ -// Returns the mean of passed parameters double mean(double, double); -void print_pointer_to_get_value(); -double calc_mean_using_pointer(double (*pf)(double, double), double number_1, double number_2); +double product(double, double); +double sum(double, double); \ No newline at end of file diff --git a/ctypes_and_api/readme.org b/ctypes_and_api/readme.org index e3a32fc5ca6738f068799b3a91f050ac72bdd225..160f4344133d977a6f0c70b956727b4739645cba 100644 --- a/ctypes_and_api/readme.org +++ b/ctypes_and_api/readme.org @@ -17,14 +17,11 @@ then run python main.py * Some leads: - -# 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 - -# https://stackoverflow.com/questions/49635105/ctypes-get-the-actual-address-of-a-c-function -# https://blog.regehr.org/archives/1621 -# https://www.oreilly.com/library/view/understanding-and-using/9781449344535/ch01.html \ No newline at end of file +- 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 +- https://stackoverflow.com/questions/49635105/ctypes-get-the-actual-address-of-a-c-function +- https://blog.regehr.org/archives/1621 +- https://www.oreilly.com/library/view/understanding-and-using/9781449344535/ch01.html \ No newline at end of file