From 07bcd27e2d3b5e282d0fa6dfa292a213ac4308c0 Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Tue, 5 Nov 2019 19:06:05 +0000 Subject: [PATCH] working example of this idea is in ctypes_and_api --- casting_pointer/main | Bin 8416 -> 8488 bytes casting_pointer/main.c | 55 ++++++++++---- ctypes/compile.sh | 2 +- ctypes/main.py | 37 +++++----- ctypes/mean.c | 6 +- ctypes/mean.h | 3 +- .../__pycache__/functions.cpython-36.pyc | Bin 0 -> 653 bytes ctypes_and_api/compile_shared_lib.sh | 3 + ctypes_and_api/demolib.c | 36 ++++++++++ ctypes_and_api/demolib.h | 5 ++ ctypes_and_api/demomodule.c | 67 ++++++++++++++++++ ctypes_and_api/functions.py | 43 +++++++++++ ctypes_and_api/libmean.so.1 | Bin 0 -> 7984 bytes ctypes_and_api/main.py | 22 ++++++ ctypes_and_api/mean.c | 20 ++++++ ctypes_and_api/mean.h | 4 ++ ctypes_and_api/readme.org | 30 ++++++++ ctypes_and_api/setup.py | 11 +++ python-c-api_solution/demolib.o | Bin 2096 -> 0 bytes python-c-api_solution/main.c | 16 +---- python-c-api_solution/main.o | Bin 2744 -> 0 bytes 21 files changed, 305 insertions(+), 55 deletions(-) create mode 100644 ctypes_and_api/__pycache__/functions.cpython-36.pyc create mode 100644 ctypes_and_api/compile_shared_lib.sh create mode 100644 ctypes_and_api/demolib.c create mode 100644 ctypes_and_api/demolib.h create mode 100644 ctypes_and_api/demomodule.c create mode 100644 ctypes_and_api/functions.py create mode 100755 ctypes_and_api/libmean.so.1 create mode 100644 ctypes_and_api/main.py create mode 100644 ctypes_and_api/mean.c create mode 100644 ctypes_and_api/mean.h create mode 100644 ctypes_and_api/readme.org create mode 100644 ctypes_and_api/setup.py delete mode 100644 python-c-api_solution/demolib.o delete mode 100644 python-c-api_solution/main.o diff --git a/casting_pointer/main b/casting_pointer/main index 10c9409e09421519a3288a986fdb6b63949d7adb..189576e722ca7e9badc90be42295a87e88e9f158 100755 GIT binary patch delta 1418 zcmZuxe`pg|9Dna(+DlkX&ZbSRCOL)FR5A4zTGT>MjXQ^hF^$_w#fIAAuxPPCt1xR( z#8iSUUjzje^`B*PN=INg5t%E~bRxvT@CPFC59JWSQb9AD^!&cNceNA`?mq8*zMt>+ zeZKGAT~0}@8wgQtu=XeCkdqkKkaO_Kt$7*IoK43TlO`?j2fgPx+;{%X!7IL-;feZ| z2lrYR`0e?o^cmrU;Cdnuq9)7Q3}`q7m+YfozNLg{zfb7;!1m#&ns}ieeJzi<q(~kg zO`~HjcVtvO8Oe9JLK!s?(HNnr$%fmQb{*>wt)JzNz`2rO?-DifBPygwjwL_BJPmWO zk~@NvXzo*?XqJ&#Jv%UBt=gz2?W(Tpn32Wd*XEEFd31yIttRf^x^-+_)~+^IL@fqU z&kE;mh`p1ls!7#-Q<Y=hQH6e36~|=!D#p=@y@<KYIqTS-=M%$u9-Xr-(9A7}W|(u_ zi@RDWS~R?j40nWGfnzH$jS%HqW!t92LnW$g-JA?wu*)Q>CKof@q9lr&67M$GvP~A% z+eMr9z5u<YQD&TMZSRhgV22#+Ai*xV`-emAtL0$lPA3U=%e!LT2E&Oi{#IaCbtB6q z#M4OU*w(NYfyH_Xx}HKzA!ZS;BlaNvh23h1{~?OF2NIrLh!Q^u<3L4XH{veDdTi|k zVhS+}OT`63eF2)qu#g#tezB%HJB|ggkaf+)0bBgv0{kQT=l_lCtz|J~ru(?CzO3ZH z7o|+jWasdHUVv9(^~Rexe1_5n#7Sw-C+Sn9$1y%UH7?vT1RIbm;GHVMLdQCB1DefZ zR}gcTrw1JW3oukxFT}<4tFk+`ui{g^vSN7Ih?^YwEH4r312dK8(?({IkR$y;x<-Xx zo$yQfejy{md{0>D65$(94LuD9J<BU*k(uOOiJ4;bg~KiIvnNnH-9$55X6k;fF6XPY z!l1`X<Hi$UUWIq|MXr3zl|HWg4PqYe>OV0m30@+)WzL&$pYc<goWY|{c{L)!<%*iw zXZiGq-Hb2dve)pu!rPSR(dDHkZ5#y-i=02tEv@BQHvA_rGwx|-T*%AtfR@u*P%6Fj zW%~Qd@2J$achCOzeeoT!Jv(=_#X38e!I1ZgJ&vEkvUGFR%NcYG6knaw+Pb(1hkPp~ z>)0$*p)U}CoX;&;2WMdmP=B2ia+vNcJdsxXI;E|k$g3O|E6rd8`f&E5%A8FAtqyzy DR2qk0 delta 1020 zcmZvaUr19?9LLYO(`|P--PQfWbWUM&2F^mrRg_#yxQiiDS`tYa83qN05ha0&VO?aQ z{9YuIvK|y4BD*MNA=8Fpy+jm=PxYW&s)t38V$R#|Zo4AZfpb3R{(j%{`~L3Xj8uK$ z`+W3qf61_^lO>7K$@VWz7s`g@*G`6#VG@Fu^qti<v$|qCa=v3IFC(~AJ{=m_ysDQ5 zm~|#=4?~C$HcM2+VLJ?^$97fXhdi;VD1D8vsP}ZZg>d?eq9}q`E#r0~v7JNtA2gX% zjpUoC7J4x)R>zPrL7bQCFg9((EGj>3DQl8SR8+5_a!nA`N@H7je=?8pdHEbVO_EB? zExftp&nmcsJ3{*S)BLHR_?fTg>q22qjowY_g>b3Lle`!YioZi8%R=`Lqc9WK$-{9d zGuAiOHMd<So>miSyWHM<(CxW$(M0HO-68d!)E*n+iZXz_hm0TxkS)k3*v=wy9Jz-4 zfOO*hv|wui<RY>Y3fW@D7l-4lpPAf%cGjC4*-#X<t~T;;a~9`p9Hv+oGaiR^HrM+Q zBQMaYSC#RZmLBG)S<m!j81U#Z486wb+k`WwDq|X&)uK5xS#qR^DaPP(fWmWgfQcHU zZ{|5&Fq(P`YB6o-h=siWZ=56Ao6)o?btIbvV2ra#nb{90bDM?HoEwa6fFi4(i5TF7 z)l0kKmbDzB);w;fqX0jx4q5~KxL#1#eO=hLg*b3=Z?_@$F`i8_$)G+N&QE0@K@*;R z23<Bs(JRz&+xkySY2K#J)*4{S=B0PxtIZKyN*FnbWrxv9N<5V^N?bJ-`mPpd9RKK7 z6Af^1&F-KdCDGnM;g@4ndg@$Gqg5d0mzlJmjv8P#e?O<)u0|(_xdq^JSvc)}HHIMQ jD&qpFXQ5G$M3+M8UJ%_CY^y!_kEO8SuAqZJ3yc2(@Yxg7 diff --git a/casting_pointer/main.c b/casting_pointer/main.c index a93ed26..e4f227f 100644 --- a/casting_pointer/main.c +++ b/casting_pointer/main.c @@ -1,14 +1,23 @@ #include <stdio.h> #include <stddef.h> - +#include <stdlib.h> +#include <stdint.h> typedef int (*fn_def)(void); + +typedef double(*fn_def2)(double, double); + int test1() { // function to call printf("Test\n"); } +double test2(double num1, double num2) +{ + printf("%f %f", num1, num2); +} + void convert_and_call(void *fnvptr_val) { // convert into pointer @@ -16,26 +25,44 @@ void convert_and_call(void *fnvptr_val) fnptr(); } +void convert_and_call2(void *fnvptr_val, double num1, double num2) +{ + // convert into pointer + fn_def2 fnptr = (fn_def2)fnvptr_val; + fnptr(num1, num2); +} int main() { void* fnvptr = (void*)&test1; + // // print adress + // printf("%p\n", &test1); - // print adress - printf("%p\n", &test1); + // printf("\n\nchar try\n"); + // // To char + // // cast into char array + // char* a=(char*)fnvptr; - // cast into char array - char* a=(char*)fnvptr; + // // print stuff + // printf("%s\n", a); + // printf("size: %ld\n",sizeof(a)); - // print stuff - printf("%s\n", a); - printf("size: %ld\n",sizeof(a)); + // // cast into new void thing + // void * fnvptr2 = (void*)a; + // printf("%p\n", fnvptr2); - // cast into new void thing - void * fnvptr2 = (void*)a; - printf("%p\n", fnvptr2); + // // // convert into pointer + // convert_and_call(fnvptr2); - // // convert into pointer - convert_and_call(fnvptr2); -} + void* fnvptr3_old = (void*)&test2; + printf("%p size: %ld\n", fnvptr3_old, sizeof(fnvptr3_old)); + char* fnvptr3_char=(char*)fnvptr3_old; + printf("%s has size %ld\n", fnvptr3_char, sizeof(fnvptr3_char)); + void * fnvptr3_new = (void*)fnvptr3_char; + printf("%p\n", fnvptr3_new); + + double numval_1 = 6.5; + double numval_2 = 5.0; + convert_and_call2(fnvptr3_new, numval_1, numval_2); +} \ No newline at end of file diff --git a/ctypes/compile.sh b/ctypes/compile.sh index 0c12caf..e5b0c00 100644 --- a/ctypes/compile.sh +++ b/ctypes/compile.sh @@ -1,3 +1,3 @@ # Compile a shared library gcc -shared -o libmean.so.1 -fPIC mean.c -gcc -o main -fPIC mean.c \ No newline at end of file +# gcc -o main -fPIC mean.c \ No newline at end of file diff --git a/ctypes/main.py b/ctypes/main.py index 67ad75a..763d023 100644 --- a/ctypes/main.py +++ b/ctypes/main.py @@ -21,31 +21,32 @@ def buildLibrary(): if not s==0: print("return code:\n{}".format(s)) -# Building library -buildLibrary() +def loadLibraryFunction(): + # Building library + buildLibrary() -# Loading library -libmean = ctypes.CDLL("libmean.so.1") # loads the shared library + # Loading library + libmean = ctypes.CDLL("libmean.so.1") # loads the shared library -# # -# 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))) + # # + # 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 + # print some stuff + # print("pointer to mean function (via python code): {}".format(mem)) + # print("Hex memory adress: {}".format(hex(mem))) + # print(type(hex(mem))) + return hex(mem) +hex_mem = loadLibraryFunction() +print(hex_mem) # Other uses of this code diff --git a/ctypes/mean.c b/ctypes/mean.c index 31d4667..c8c1d17 100644 --- a/ctypes/mean.c +++ b/ctypes/mean.c @@ -1,6 +1,7 @@ #include "mean.h" #include <stdio.h> #include <stdlib.h> +#include <math.h> double mean(double a, double b) { printf("calculating mean with %f and %f", a, b); @@ -16,9 +17,4 @@ double calc_mean_using_pointer(double (*pf)(double, double), double number_1, do 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 3fdc9b1..035946d 100644 --- a/ctypes/mean.h +++ b/ctypes/mean.h @@ -1,5 +1,4 @@ - // 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); \ No newline at end of file +double calc_mean_using_pointer(double (*pf)(double, double), double number_1, double number_2); diff --git a/ctypes_and_api/__pycache__/functions.cpython-36.pyc b/ctypes_and_api/__pycache__/functions.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5427d3f43ca347265356eea27b4a32d18b28153d GIT binary patch literal 653 zcmYk3&8pNe6vvbFV``myMcuh_A!5NhMcj#sFyd;Mjjjq((j-IMn>Hm$2WFgEjawhY z#}IsqY+d;Zt~}{n<p$12NX|d!{PObRA`O53`1~e9=oh-R2;}d;%yV!YaV$}Bj<~?n zo)m-=9(+Ybz(XEE3_1RYviLVtpf&T}FANrfEy2t)a2B<gV_*A?9MJ*s@S2z>mhh+z z4(NnW7{g0mX}y0`QByx=sv8<9N>fuUcqyA|Vd_sAc9E%tl-fVBzo&&Abq|-hc$I!R zW}!>XSPfb+VT?;zE!cI*sFW@mbkkcGZ<Ow+1s!a@Bb|WCpJiUFPUM_!8=gaLE0{I; zu(P%5uh<oo3B93A<jn2{VM^Nbk`7J28GB|M)tkkzbMtC!Bwsa^rg{ftk%_^f;1VZT zr;z=J<1q(d6P%}zSabqn7Po{0h@;N{N*h9qPNa>G_~0Rv^?nW*Izjt|QHvMZY|?e{ zxh)qi->+6KWYpLq^tW8X%B^a6Ik;#`<tQ>z%x)B1(1~su|LpESAMT-4^xp^{Zibt~ zf$^9SiGwtKaH;P@o<;gD1V@z7ewL||>ExECuhNrn^14%el;W-bwMi`jED1?we*y5y Bo{s<k literal 0 HcmV?d00001 diff --git a/ctypes_and_api/compile_shared_lib.sh b/ctypes_and_api/compile_shared_lib.sh new file mode 100644 index 0000000..e5b0c00 --- /dev/null +++ b/ctypes_and_api/compile_shared_lib.sh @@ -0,0 +1,3 @@ +# Compile a shared library +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_and_api/demolib.c b/ctypes_and_api/demolib.c new file mode 100644 index 0000000..0d4af8c --- /dev/null +++ b/ctypes_and_api/demolib.c @@ -0,0 +1,36 @@ +#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) +{ + printf("test for running function with mem addr %ld with arguments %f %f\n", str_1, number_1, number_2); + + // 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); + + 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 new file mode 100644 index 0000000..8059060 --- /dev/null +++ b/ctypes_and_api/demolib.h @@ -0,0 +1,5 @@ +// 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 diff --git a/ctypes_and_api/demomodule.c b/ctypes_and_api/demomodule.c new file mode 100644 index 0000000..90914d6 --- /dev/null +++ b/ctypes_and_api/demomodule.c @@ -0,0 +1,67 @@ +// demomodule.c +#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) { + long int str_1; + double number_1; + double number_2; + if (!PyArg_ParseTuple(args, "ldd", &str_1, &number_1, &number_2)) { + return NULL; + } + + double result; + printf("%p contents %ld\n", &str_1, str_1); + result = calc_mean_using_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 + METH_VARARGS, // received variable args (but really just 1) + "Calculate the mean of two values via a pointer function" // 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/ctypes_and_api/functions.py b/ctypes_and_api/functions.py new file mode 100644 index 0000000..ccb9b38 --- /dev/null +++ b/ctypes_and_api/functions.py @@ -0,0 +1,43 @@ +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_shared_lib.sh", shell=True) + if not s==0: + print("return code:\n{}".format(s)) + +def loadLibraryFunction(): + # OLD + + # Building library + buildLibrary() + + # Loading library + libmean = ctypes.CDLL("libmean.so.1") # loads the shared library + + # # + # 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 + + # print some stuff + # 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))) + + return mem \ No newline at end of file diff --git a/ctypes_and_api/libmean.so.1 b/ctypes_and_api/libmean.so.1 new file mode 100755 index 0000000000000000000000000000000000000000..df6280d836c719bec47c764d75c8a0222edbf955 GIT binary patch literal 7984 zcmeHMYitzP6~61W!2#o4XbKLd%A^9x5M^po2o5R1*sK{^n-CXE^x+QUeb}q)!`Yop z?1)eo(iR7yqE<qvO;!FyRTT-TKN_M+F$JMSRV7DBE2Op(X%uPGBGnMJa;1jtId{&t zo}FD+>7V}Mu4c|X-+A0S_c3$s*>A@N2bw}5g%VazD&{V=cu21Zx;vyoq*wK*m2}^v zI<>B-E-CnG|8DgdP^AnFa2qS=YHimnQA1ZijV2H85(+zJ*{(zEI>ZiiP96nRnpe$a z!`E9P57Nyf;{wXMTn>NeCb-@zj)HWD)=~--c2AQX_w&=1s3;Djy=BH_QTh)mtbVrp z$w!#31BXUb%g8gW!{smS>KPe&@;e`I{l)ytmtNu~SkC=oJEo`SdP2R;eOtMHA6;wc z>WlsU)*B!E@c4_b+<yN(cf+4<JbQFg>IXkQe);U}_P@RRcj*}^HYl42GaBFyVe1;; z+z+Dx-m?roO!(&;=wBo(s@AKns8J*RrN%d??f`y*@O7$9eIk=|OspmZ|D)h&>s7*| zYD1m>Y0-aK^q&?#JfG`mM2`hF$9j#gQO8z_B8Y8|XY)C`=sE@0ww0aErCnvGh$#Eu zks&*gEF{O%MK@VEGSr{R=aNU9u}spFHI~@%DTf_6ne+=uHCagK+>}S`$viR1g6-z* zY|_c8xRZ(Nnq4ZUbK{V!OnNMC7W3v~%1$O6*HN}TRxEm*Bq*0q2L=!J_1lk{kD5F6 zlX%;;iPl&B?>uQ>otHMIX}LA2*X8-K@3CKJWIUsIFNj{R;D*d6^ugbV7+RCncx|EF z^x?b*P|7}hH9(>ZJ{)_R#fv`NKeZjwAD&ik3|Lz!>(s4Q>r6{&m7%Qf&bdvMdF#}* z)~lY7?v<S<NmSYL65S&Y_EL>`UWMwTn-wZshKWy|gMoE+&$9%KSZ7<(M6Jgct=SLV z2dIfv%u*9;Mk_Z{X5>M=-PPz-_PWHA{dQJ7yK|d%v-K|7TUYLet=R?ZN_nppx^BI5 z*X<yO@7(7(Y-5MZ`J37EKB=kF7pzlzUgg>d_ovM|v*$O&mG{sSlr6elZ@El-h`Tex z&+_qAa=G7AAN?pr8f-|TW!#CZjV;n`XyHyI8e6c=#1>PLuD7h&Sebz`J;ATY!RtKA z<=@?{R2U_LqcJvE^Dxc&oyfPYynR(WJk!!d?OL<f$?PJV(WT1g$?V*yr*Z05w>A4B z`Cc2l$<5wie>bc%BR8q(ve)#;JcIL<`IHqoF-Kil<Zco5aPsZ4Z(eZa-RRQWJj;6i zeKXEGt(0+G+GPfBJ>&VbJ7H`|8BQ)iM9I!H+`K1Fm2z=6ozEFv&!rtBZp8D6<ksEB zmdRD*oJt{CEM;7yP|D@1E~_@$x6h+Hku)GAA1TiT-+M!y;V1YT#%p@&lS<_<(F;VU zh@RxpBKj`TOGN)cbe<>|{^oEAy)djoQ_)ao+sf8+G!B~y)87K}VX#7bbfCTC%aPU3 zx6Y`&8=u(r#m)NF%J#GjR0rv`vYr&S{U%+1C0xH#_q9jA*VMmeMbjX);Q2mI@=ofD zb_DsT7VEZOA^GP>evGJsyy+XB0%P~ey%D%K0{2GX-UukfTZpd^J8{g$rOhMNc$Uuz zToA`T;IY+nTqk&;8-*gC+Z2$~Hzm)|f;5cS>a+xF685Pc39jVxr>=>g)j~UjR%1Mg z%fw7Uj_(%2@C{;TNyETTH+uqno90B1&q`e2k3KWH{}ZB50gdJ{jtjyMiu_-~SNrL? z`@i3DZVonlUd91&^@0BW-A32QSSjb0j9umqv-^?lCCzO=vAxIa-eGRv>fu38^?aBj zbDY2Z(lABNnEzTlT%Gq?yjfv=)Z#4)<6MicP?(=ue5JxX*W#@T>!B8}Ki9E5tX8QR zEL@*KSglqU8{%!%Jd01A{4_WpYX9wO5)0F35LS_De!>TnpQ!4^!u1KlYHf9&`e4#u zr?5Y3@y}4c#qdMA9;WCI=Pkc5tUgNzy+-=$71mR&e*L+c<>Bh?TGHnI)U0k-mJqMT z@24huOCfIsdAr~Xf$@JxaJ=uJzl$m%-#H)qcR=Iy<C7IXcz?nV=LJFy#`yx_jrzab zbNx*FiK@j0^VrDGYg)g4oZrxR{XFs+MKxGIf6)5%`INtCyncQc2{-5pmiy_!8s%j= z318P>oj;`UpckcfYP?Ma^D<u{+^APqUniXNHNm`(EqE|bG(b4#gMxXSX9N%CiB1vT zsNJ6uuFoTZK3&#+8oW2+1-IyyQYka8mQp;no3-Pd<SA0dC6TwsGx;$mV<+5vp=dj$ zDHYFWCo@SmnJ{-f_V}*GN;-LDJB5NXO{p5UFs)JrC!4errEGSZOnjWqHr1%|*_66u z+XKV<hGKT?(0)!z*@<G_o}i;DXP)+d?a;oVgZ+e3!qJXdqH66QCWw+$Fgh^!RNuZq z`>BC}uf~qpNA~p%#>mxw%V|ljNhiO&yj5?nKhdNyB&n)NtY8L>(^LL@)pAKL-IY&~ zLaXhAm!MN-aXRZdV?^D8M<-Cr<=vz?o-3JSrF16oNIIc3H{lc~l$n^$k)=o7f+u+{ zSt!y`zlO0%R!C+XHjvt6##N?H51Ldp$MeLx$tk+)0W%AEovJgF6EejU3339?Gxg@$ zvp}6%aI)z*HJ^9cGj)zrekNu7lt~LNON%J5s{ePE<3fLq3~>PH=738Hm#U~qwSQ9V zgm@0|0_c9xL|heoZT66yV@22_o&-Hi`;-f}%T?GT&g&(NeZwB{2k14D`HQ%#LKf9H zHiSLm6i~#)=s)y8N64OIP4I|kKn-ar*nfdlf+{S7J>nkFIZ;IW!ROD3eV^zdJ_5x! zu|0hy>c(%1Fdh@c^T>~bA`T}NUAV9QQY6N2k9Z5z@GDb2Dm*CX{r&bAB`yHP^TG{y z(C-KA5pRIL7MO6f3x8(=_BcO*;#>j!;Pd}T>@k0c2SG2uP$>Eh_$LAT<^Iotez5(Y z2ka4Fg8mwYLWAw||1lhsRo9oqmDT?Nm$8SRH%T7x*&|+!vQsM1^SC7*_-{$TYY*)s zuEqa}b25K;ZrEWSPm(RGz#j4M4ek_`E{|02um^pQB!2s9oGc9(RZFh|JJ3G|>=92J zVh=sI3GyG1fHCwRaZuMX_JQTB%F=!}8W0NmhXXk5{S<50uX<G4?~?t<`GRe9q5pWV o@cuyG{q{5bvZ3-O8uC~@)>74EE!`X0@0AzNZND<r1Mbv+0Q-+GSO5S3 literal 0 HcmV?d00001 diff --git a/ctypes_and_api/main.py b/ctypes_and_api/main.py new file mode 100644 index 0000000..b3af562 --- /dev/null +++ b/ctypes_and_api/main.py @@ -0,0 +1,22 @@ +import ctypes +import os +import subprocess + +from functions import loadLibraryFunction, buildLibrary + +import demo + + + +buildLibrary() + +# Loading 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))) + + +dong = demo.calc_mean_with_pointer(mem, 1.0, 2.0) +print(dong) \ No newline at end of file diff --git a/ctypes_and_api/mean.c b/ctypes_and_api/mean.c new file mode 100644 index 0000000..c8c1d17 --- /dev/null +++ b/ctypes_and_api/mean.c @@ -0,0 +1,20 @@ +#include "mean.h" +#include <stdio.h> +#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; +} + +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; +} \ No newline at end of file diff --git a/ctypes_and_api/mean.h b/ctypes_and_api/mean.h new file mode 100644 index 0000000..035946d --- /dev/null +++ b/ctypes_and_api/mean.h @@ -0,0 +1,4 @@ +// 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); diff --git a/ctypes_and_api/readme.org b/ctypes_and_api/readme.org new file mode 100644 index 0000000..e3a32fc --- /dev/null +++ b/ctypes_and_api/readme.org @@ -0,0 +1,30 @@ +* Idea: +- In the main function we compile the functions mean.c and mean.h to a shared library, calling it libmean.so.1 +- this library gets loaded into memory with ctypes.CDLL(<name lib>) +- the memory adress, and two floats get given to a c function that is bound with python through the python-c-api: + - these are defined in demolib.c + - these are connected with python using demomodule.c + +- within that c function, the memory adress is made into the pointer to the function that is contained in the loaded shared library. +- This pointer is then called, with the two numbers and returns an output + + + +* usage: +in this directory: pip install . --upgrade + +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 diff --git a/ctypes_and_api/setup.py b/ctypes_and_api/setup.py new file mode 100644 index 0000000..0354312 --- /dev/null +++ b/ctypes_and_api/setup.py @@ -0,0 +1,11 @@ +from setuptools import Extension, setup + +module = Extension("demo", + sources=[ + 'demolib.c', + 'demomodule.c' + ]) +setup(name='demo', + version='1.0', + description='Python wrapper for custom C extension', + ext_modules=[module]) \ No newline at end of file diff --git a/python-c-api_solution/demolib.o b/python-c-api_solution/demolib.o deleted file mode 100644 index ffc6c06f550025b0a750c2196115c828d48087e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2096 zcmbu9&ui2`6vrpK+N%Ajh^Y0jC#hoNE*8`xvTaElWVK+MgRPQgcT>AI$u7GIYzy@V zD?-S{g9nd-e}MmjP(eH>d(s|zsF1^6ym=_p_mY|H7_t}rmdtzaGw;1gXEOUtD$Jz> zfiMZ=Ht9x;5|TaI_49$7Cxc{wD6;$0-R`)K?<pNm@`bi59eC2gqaAKW>WqAle12k4 zZgs|GcY9ZMown>rU_blVR(5wFY)7H6E4MxhQRqs(>?ymD;>+&$2zv@P`5Qsl`ZT^0 zz6dOrf#rPH*>{ya@9v(b>|=%d&HZsmU-`=pnV+4V%8V;T$FiNwb#YS6PUM^*%0129 z5VMnF?o!BuEr8)Pb%d?^L}-o*V}t$2Uc&}n0FDppJPy;tqpwo4LwyP)K!|g<kb}<Q zz~-02`3#_k$U!w6*u2zAr`EbT&v6cP83&f5hx3Sf3D5Wl`E{5ypHBP&2uZ_VlG4yA zNomrTgrQ4+56*pLG-CklDeirOy##iKaux@B2<#%|*TABJy#sp{o>2rbNf0OTLJz*! zgD>~s8gP97_h3=MIiXY5&8kr;iY20z%c|v=MZHc;$FM6kV>61i4P9;6b)wD}7G|ak z>cZUIqO_zgP0ti0mB5UlTg221qgukKRND-UW^-Ltr%|yUtF>yyvSE!-`2V5s<Obn6 zI1IId5ESQ6LLBfR@LB!~jt_JE4aY|~o}oMi79XZObr@&ox*Fr`TwlgG+g~C!HceYA zg0<_RU1wfhH#E`Kn>G>4nynGB*k};3R5eZA0%lchU7WwCOf+n*v_ZrmU0+w%>YAz3 z<^J1bpab5$_|3=zLwyZRG-58VF$nN%@;n6pH@%uo%8!G^TKug+oefQJKaj_7@=$ys znjgnkfMd^pt<OO%_RPY=i>;6Sd9n4Goq|c`^LaOuU_$N!W&F2?ee$&a9R{4({xNh1 zoTUA)Aq1@kBO$o|_$$Zi+5Y1)@wKsJkFNig+7q-kUXOj_dyn-^3b!!eMB7E=BzQ^n OZTkKXqRh~V*Z%>Bg$Jep diff --git a/python-c-api_solution/main.c b/python-c-api_solution/main.c index 27d24aa..4d412f8 100644 --- a/python-c-api_solution/main.c +++ b/python-c-api_solution/main.c @@ -2,11 +2,6 @@ #include <stdlib.h> #include "demolib.h" - - - - - int main(void) { // Testing stuff for add_number function int getal_1=2; @@ -53,15 +48,6 @@ int main(void) { function_via_pointer_res_2 = add_number_using_pointer(pf3, 10, 20); printf("result of calling a function with a function pointer to multiply_number: %d\n", function_via_pointer_res_2); - // - - - - - - - - return(0); -} \ No newline at end of file +} diff --git a/python-c-api_solution/main.o b/python-c-api_solution/main.o deleted file mode 100644 index da6dae0c35829ddfa9513192e590a17c9e87cb85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2744 zcmbtW-)j_C6h512)!M{v#fPAM7^#XWb;zQk1{(5%N#<cOqFH<?46~bAvt)NR?A)bE zACf|$uuO&0r~U(l{sV<jL<PlI$b$uuJm#g4hl2VRp^%<4_uSp<bym=xaPK|$JKy>4 znYs7QX5B5$4CHd4EC=Jzn<*4v<zUaBNZkn-f<Y*Goxi>B|GBp5ZVVv2>E5w$NJ@7S zccb&Hv$;#$j(b0G?{^+~x4)w426bt`yZs^gUdMgXbGN;ugbkt2GmjOJv4hZ#mnD+o zawRWOg1boHz55ZW-y>-MNymMdxDPY)Rn7~{dGW_Fq~AT9mZi#noVbtQnz@IWds&%V ziMy4NnZANQ9{{w%xLp@^vuXzm3$^H$9km<fuoaKlrxy-G0A;L$tjDV~qe>tIabwZK zfw(c%OV;DHW1<B1a<dkRuw{#;Efzys#+Pf@)pk@7wPqyOGV?1zy)G3L&;F(+7E!S~ z*Q9&0Qmt3VyXiFWZPb?Qt6U?OHak5%W}hvU+mUG7mz)dE=($2WofXy!mz~iIPGLmi z@+kml6UlPlUWeRDK6hg9;Gv)JV1I@fHL`I!=#xkCKMYI{9k8zCkdoqA9Z^4km-|^U zEAz$xSooJ^7Aj?#1?fS2BV>Vg`Lw77+4Wj*Kx0Xlm`Alb(`QF)2wPrKUh6;agFAij zi+%9%KKOJW{OdkAG=f^>RMG+b+2Y*PWYM3SnYrQ4`}31iMc0Sk5rk#D7ov*frO?Mq z0@YR+YH>fk8$KUjFwPuS0B|zxY0m*Z#`f>Nv{A<CV@JEC@G-`TKd9l8j4S?eo)-;V zoyiL0q(gh7^xFpi6wlXrG}lcu{0RC==V!*hz)^p$-x*hRs`~CRZt6ekqqC#&KS5uu z`<!v5|0B;|X?*>?siR7D()m<6$LS)XQ9Zi;2;)lsY03gPukm$#o8!c%)-@+yZHS-@ z4xSr1E-J4T)&oa`D*~K_Km_2F;~1P)Q%)+)Mk9<c7Bxla%w8>>i$zdbLIS0Qi+;5g zG{WvW|I@KCpB~M;=@W>NsrxNwlB;|gPhg{WIDt*KVg3Z|@Oz`*6>`;=W|+xm7&pIg zYn;cl?qI@SVuUo`H@|?nr1{$3;ru&Z=(Mq*svjw-UBR9x>OM;p;8zx;`gBurYMjEL z@^#){W<eY@xi>lAq;E5DSr<j$tp7S<S^Kxg2SV)=?H}c;e1%gz=Gq8Bo;TzdE||U% m^iPzTPnfxP2*Gbu6k1&l-QIluPcf2}pXZ;tpqnWjGygx;x~S~{ -- GitLab