Skip to content
Snippets Groups Projects
Commit c230691f authored by David Hendriks's avatar David Hendriks
Browse files

Cleaned up code of ctypes_and_api. will serve as the example for the...

Cleaned up code of ctypes_and_api. will serve as the example for the implementation in the python-binaryc
parent 07bcd27e
No related branches found
No related tags found
No related merge requests found
No preview for this file type
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "demolib.h" #include "demolib.h"
typedef double (*fn_def)(double, double); typedef double (*fn_def)(double, double);
int add_number_using_pointer(int (*pf)(int, int), int number_1, int number_2) { double run_function_via_pointer(long int str_1, double number_1, double 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)
{ {
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 // convert into pointer
fn_def fnptr = (fn_def)str_1; fn_def fnptr = (fn_def)str_1;
printf("size of function pointer %zu\n",sizeof(fnptr)); // print some stuff
printf("%p size: %zu\n", fnptr, sizeof(fnptr)); // 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));
double result; // printf("%p size: %zu\n", fnptr, sizeof(fnptr));
result = fnptr(number_1, number_2);
double result = fnptr(number_1, number_2);
return result; 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
// Example header file double run_function_via_pointer(long int str_1, double number_1, double number_2);
\ No newline at end of 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
...@@ -2,48 +2,26 @@ ...@@ -2,48 +2,26 @@
#include <Python.h> #include <Python.h>
#include "demolib.h" #include "demolib.h"
// Declare the function wrapping the python call and the c function
// https://stackoverflow.com/questions/51505391/how-to-parse-void-to-pyobject static PyObject *DemoLib_RunFunctionViaPointer(PyObject *self, PyObject *args) {
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) {
long int str_1; long int str_1;
double number_1; double number_1;
double number_2; double number_2;
if (!PyArg_ParseTuple(args, "ldd", &str_1, &number_1, &number_2)) { if (!PyArg_ParseTuple(args, "ldd", &str_1, &number_1, &number_2)) {
return NULL; return NULL;
} }
// printf("%p contents %ld\n", &str_1, str_1);
double result; double result;
printf("%p contents %ld\n", &str_1, str_1); result = run_function_via_pointer(str_1, number_1, number_2);
result = calc_mean_using_pointer(str_1, number_1, number_2);
return Py_BuildValue("d", result); return Py_BuildValue("d", result);
} }
// module's function table // module's function table
static PyMethodDef DemoLib_FunctionsTable[] = { static PyMethodDef DemoLib_FunctionsTable[] = {
{ {
"calc_mean_with_pointer", // name exposed to Python "run_function_via_pointer", // name exposed to Python
DemoLib_CalcMeanWithPointer, // C wrapper function 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
},
{
"calc_mean_with_pointer_test", // name exposed to Python
DemoLib_CalcMeanWithPointerTest, // C wrapper function
METH_VARARGS, // received variable args (but really just 1) METH_VARARGS, // received variable args (but really just 1)
"Calculate the mean of two values via a pointer function" // documentation "Calculate the mean of two values via a pointer function" // documentation
}, },
......
No preview for this file type
import ctypes import ctypes
import os import os
import subprocess 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() buildLibrary()
# Loading library # Loading shared library
libmean = ctypes.CDLL("libmean.so.1") # loads the shared library libmean = ctypes.CDLL("libmean.so.1") # loads the shared library
# Get memory adress of function. mimicking a pointer # Get memory adress of function. mimicking a pointer
mem = ctypes.cast(libmean.mean, ctypes.c_void_p).value mem_mean_function = ctypes.cast(libmean.mean, ctypes.c_void_p).value
print("mem adress of mean function {}, type: {}".format(mem, type(mem))) 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) result_sum = demo.run_function_via_pointer(mem_sum_function, 10, 2.0)
print(dong) print("Result of sum: {}\n".format(result_sum))
\ No newline at end of file
...@@ -3,18 +3,23 @@ ...@@ -3,18 +3,23 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
double mean(double a, double b) { double mean(double a, double b)
printf("calculating mean with %f and %f", a, b); {
return (a+b)/2; printf("calculating mean of %f and %f\n", a, b);
double mean = (a+b)/2.0;
return mean;
} }
void print_pointer_to_mean() { double product(double a, double b)
printf("pointer to mean function (via c code): %p\n", &mean); {
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 sum(double a, double b)
double result; {
result = pf(number_1, number_2); printf("Calculating sum of %f and %f\n", a, b);
printf("result running mean function with pointer to the function: %f", result); double sum = a + b;
return result; return sum;
} }
\ No newline at end of file
// Returns the mean of passed parameters
double mean(double, double); double mean(double, double);
void print_pointer_to_get_value(); double product(double, double);
double calc_mean_using_pointer(double (*pf)(double, double), double number_1, double number_2); double sum(double, double);
\ No newline at end of file
...@@ -17,14 +17,11 @@ then run python main.py ...@@ -17,14 +17,11 @@ then run python main.py
* Some leads: * Some leads:
- https://solarianprogrammer.com/2019/07/18/python-using-c-cpp-libraries-ctypes/
# https://solarianprogrammer.com/2019/07/18/python-using-c-cpp-libraries-ctypes/ - https://gist.github.com/elyezer/7099291
# 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://www.geeksforgeeks.org/turning-a-function-pointer-to-callable/ - https://documentation.help/Python-3.2.1/ctypes.html
# https://stackoverflow.com/questions/9420673/is-it-possible-to-compile-c-code-using-python - https://stackoverflow.com/questions/49635105/ctypes-get-the-actual-address-of-a-c-function
# https://documentation.help/Python-3.2.1/ctypes.html - https://blog.regehr.org/archives/1621
- https://www.oreilly.com/library/view/understanding-and-using/9781449344535/ch01.html
# https://stackoverflow.com/questions/49635105/ctypes-get-the-actual-address-of-a-c-function \ No newline at end of file
# https://blog.regehr.org/archives/1621
# https://www.oreilly.com/library/view/understanding-and-using/9781449344535/ch01.html
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment