From 5f59a8a1171c4bebdf2b28006db78c7dd3a1a452 Mon Sep 17 00:00:00 2001
From: David Hendriks <davidhendriks93@gmail.com>
Date: Mon, 4 Nov 2019 10:38:55 +0000
Subject: [PATCH] created some cython DLL reading, i'm able to fetch the memory
 adress, but not yet finished with the ptr -> int -> ptr conversion. also
 updated readme

---
 README.org                      |  42 ++++++++++++++++++++++++++++++
 README.md => README.org~        |   3 +++
 ctypes/compile.sh               |   3 ++-
 ctypes/libmean.so.1             | Bin 7528 -> 7984 bytes
 ctypes/main.py                  |  44 ++++++++++++++++++++++++++------
 ctypes/mean.c                   |  19 ++++++++++++++
 ctypes/mean.h                   |   4 ++-
 python-c-api_solution/demolib.c |   5 +---
 8 files changed, 106 insertions(+), 14 deletions(-)
 create mode 100644 README.org
 rename README.md => README.org~ (99%)

diff --git a/README.org b/README.org
new file mode 100644
index 0000000..e90a45f
--- /dev/null
+++ b/README.org
@@ -0,0 +1,42 @@
+# python-c-interface
+
+Repo for interfacing python with c. Main goal is to be able to compile a function and give the pointer to that function to a c program.
+
+# Leads:
+# https://stackoverflow.com/questions/17980167/writing-python-ctypes-for-function-pointer-callback-function-in-c
+# https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages
+# https://cffi.readthedocs.io/en/release-1.4/using.html?highlight=re
+# http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn30
+# https://stackoverflow.com/questions/51273804/returning-a-function-python-c-api
+# https://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArray_ArrFuncs.fillwithscalar
+# https://stackoverflow.com/questions/43162622/python-passing-pointers-between-c-and-python-with-ctypes
+# https://stackoverflow.com/questions/4213095/python-and-ctypes-how-to-correctly-pass-pointer-to-pointer-into-dll
+
+# https://stackoverflow.com/questions/41954269/create-c-function-pointers-structure-in-python
+# https://stackabuse.com/enhancing-python-with-custom-c-extensions/ Read
+# https://stackoverflow.com/questions/49941617/runtime-generation-and-compilation-of-cython-functions
+# https://realpython.com/cpython-source-code-guide/
+# https://docs.python.org/3.6/c-api/index.html
+# https://stackoverflow.com/questions/6626167/build-a-pyobject-from-a-c-function
+# https://docs.python.org/3.6/extending/newtypes_tutorial.html?highlight=pointer
+# https://realpython.com/cpython-source-code-guide/
+# https://diseraluca.github.io/blog/2019/03/21/wetting-feet-with-python-c-api
+# https://docs.python.org/3/c-api/function.html
+
+# http://koichitamura.blogspot.com/2008/06/this-is-small-python-capi-tutorial.html
+# https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#including-verbatim-c-code probably works too!
+# https://www.oreilly.com/library/view/python-cookbook/0596001673/ch16s07.html
+# https://stackoverflow.com/questions/53215786/when-writing-a-python-extension-in-c-how-does-one-pass-a-python-function-in-to
+# https://pythonextensionpatterns.readthedocs.io/en/latest/refcount.html
+# https://bitbucket.org/cffi/cffi/issues/265/cffi-doesnt-allow-creating-pointers-to
+# https://stackoverflow.com/questions/40166645/a-c-pointer-passed-between-c-and-python-using-capsule-is-empty
+# https://www.youtube.com/watch?v=2B0CMF3cYPA
+# https://stackoverflow.com/questions/16993927/using-cython-to-link-python-to-a-shared-library
+
+
+* Current Status:
+I managed to compile a shared library on runtime, and also load the function pointer memory adress of a dynamically loaded function.
+
+** TODO Cast that pointer value into an integer and pass it to another function that will use that int as a function pointer again
+** TODO Test within c-script itself
+** TODO First in the dummy script, just to try things out, and then in the script where python is the bridge between 
diff --git a/README.md b/README.org~
similarity index 99%
rename from README.md
rename to README.org~
index 4ca4a36..879fc71 100644
--- a/README.md
+++ b/README.org~
@@ -32,3 +32,6 @@ Repo for interfacing python with c. Main goal is to be able to compile a functio
 # https://stackoverflow.com/questions/40166645/a-c-pointer-passed-between-c-and-python-using-capsule-is-empty
 # https://www.youtube.com/watch?v=2B0CMF3cYPA
 # https://stackoverflow.com/questions/16993927/using-cython-to-link-python-to-a-shared-library
+
+
+
diff --git a/ctypes/compile.sh b/ctypes/compile.sh
index 736d146..0c12caf 100644
--- a/ctypes/compile.sh
+++ b/ctypes/compile.sh
@@ -1,2 +1,3 @@
 # Compile a shared library
-gcc -shared -o libmean.so.1 mean.c
\ No newline at end of file
+gcc -shared -o libmean.so.1 -fPIC mean.c
+gcc -o main -fPIC mean.c
\ No newline at end of file
diff --git a/ctypes/libmean.so.1 b/ctypes/libmean.so.1
index 1ede0ce64eb59a8cf19dfffde096fbdf7fe4c32d..df6280d836c719bec47c764d75c8a0222edbf955 100755
GIT binary patch
literal 7984
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

literal 7528
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

diff --git a/ctypes/main.py b/ctypes/main.py
index d5549a5..67ad75a 100644
--- a/ctypes/main.py
+++ b/ctypes/main.py
@@ -5,6 +5,10 @@
 # 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
+
+
 import ctypes
 import os
 import subprocess 
@@ -14,15 +18,39 @@ 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)) 
+    if not s==0:
+        print("return code:\n{}".format(s))
 
+# Building library
 buildLibrary()
 
-
+# Loading library
 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
+
+# #
+# Pointer 
+print("Function pointer of the function printing the function pointer: {}".format(libmean.print_pointer_to_mean))
+
+# Memory adress 
+libmean.print_pointer_to_mean()
+
+# Get memory adress of function. mimicking a pointer
+mem = ctypes.cast(libmean.mean, ctypes.c_void_p).value
+
+# ijij
+print("pointer to mean function (via python code): {}".format(mem))
+print("Hex memory adress: {}".format(hex(mem)))
+print(type(hex(mem)))
+
+
+
+
+
+
+
+# Other uses of this code
+# 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
index 12d80b0..31d4667 100644
--- a/ctypes/mean.c
+++ b/ctypes/mean.c
@@ -1,5 +1,24 @@
 #include "mean.h"
+#include <stdio.h>
+#include <stdlib.h>
 
 double mean(double a, double b) {
+  printf("calculating mean with %f and %f", a, b);
   return (a+b)/2;
+}
+
+void print_pointer_to_mean() {
+    printf("pointer to mean function (via c code): %p\n", &mean);
+}
+
+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;
+}
+
+void main() {
+    double res = double mean(double 3.1, double 6.2);
+    printf("result %f", res);
 }
\ No newline at end of file
diff --git a/ctypes/mean.h b/ctypes/mean.h
index a52ef61..3fdc9b1 100644
--- a/ctypes/mean.h
+++ b/ctypes/mean.h
@@ -1,3 +1,5 @@
 
 // Returns the mean of passed parameters
-double mean(double, double);
\ No newline at end of file
+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);
\ No newline at end of file
diff --git a/python-c-api_solution/demolib.c b/python-c-api_solution/demolib.c
index fcb2dba..f210145 100644
--- a/python-c-api_solution/demolib.c
+++ b/python-c-api_solution/demolib.c
@@ -27,7 +27,4 @@ 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;
-}
-
-
-
+}
\ No newline at end of file
-- 
GitLab