From c49ed3b13e44e4cec1f885a41279ce0ec103b93f Mon Sep 17 00:00:00 2001 From: wangziao <1575538687@qq.com> Date: Sun, 6 Jul 2025 11:18:03 -0700 Subject: [PATCH] add files --- README.md | 11 ++++++++-- calling-c/Makefile | 8 ++++++++ calling-c/caller.py | 43 +++++++++++++++++++++++++++++++++++++++ calling-c/hello.c | 34 +++++++++++++++++++++++++++++++ calling-c/hello.o | Bin 0 -> 2144 bytes calling-c/hello.so | Bin 0 -> 15072 bytes calling-cpp/Makefile | 8 ++++++++ calling-cpp/callee.o | Bin 0 -> 1560 bytes calling-cpp/callee.so | Bin 0 -> 14912 bytes calling-cpp/caller.py | 10 +++++++++ calling-cpp/workload.cpp | 21 +++++++++++++++++++ calling-cpp/workload.h | 4 ++++ 12 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 calling-c/Makefile create mode 100644 calling-c/caller.py create mode 100644 calling-c/hello.c create mode 100644 calling-c/hello.o create mode 100644 calling-c/hello.so create mode 100644 calling-cpp/Makefile create mode 100644 calling-cpp/callee.o create mode 100644 calling-cpp/callee.so create mode 100644 calling-cpp/caller.py create mode 100644 calling-cpp/workload.cpp create mode 100644 calling-cpp/workload.h diff --git a/README.md b/README.md index 9fc3ebb..bb34cc7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ -# python-calling-c-cpp +To list every symbol in a dll, use "nm". -Example of calling C and C++ functions in Python \ No newline at end of file +"nm -g hello.so" output "T square", where hello.so is created from a **C** source file containing function square. +"nm -g callee.so" output "T \_Z7isprimex", "_Z9sumprimesx", where callee.so is created from a **C++** file containing function isprime and sumprimes. + +Why does the names differ? C++ compilers use "name mangling" to support overloading, etc, resulting in names that differ from names in the source file. This is not done in C compilers (since C does not support overloading as well). + +To prevent name mangling, use `extern "C"` directive in the function declaration. +The extern keyword may be applied to a global variable, function, or template declaration. It specifies that the symbol has external linkage. +`extern "C"` specifies that the function is defined elsewhere and uses the C-language calling convention, which includes do not mangle names. \ No newline at end of file diff --git a/calling-c/Makefile b/calling-c/Makefile new file mode 100644 index 0000000..acbb04c --- /dev/null +++ b/calling-c/Makefile @@ -0,0 +1,8 @@ +hello.so: hello.o + gcc -shared -o hello.so hello.o + +hello.o: hello.c + gcc -std=c99 -c -o hello.o hello.c + +clean: + rm hello.o hello.so \ No newline at end of file diff --git a/calling-c/caller.py b/calling-c/caller.py new file mode 100644 index 0000000..8550e2a --- /dev/null +++ b/calling-c/caller.py @@ -0,0 +1,43 @@ +import ctypes +hello_lib = ctypes.CDLL('./hello.so') #/windows + +# 1. Square (int -> int) +hello_lib.square.argtypes = [ctypes.c_int] +hello_lib.square.restype = ctypes.c_int + +x = 4 +result = hello_lib.square(x) +print(f'the square of {x} is {result}') + +hello_lib.sum_elements.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_int] +hello_lib.sum_elements.restype = ctypes.c_int + +# 2. Sum (int*, int -> int) +N = 4 +p = [3, 1, 2, 4] +# Converts Python list to C array. (*p) is equivalent to (3, 1, 2, 4) +c_array = (ctypes.c_int * len(p))(*p) +# Get the address of the array +p_pointer = ctypes.cast(c_array, ctypes.POINTER(ctypes.c_int)) + +result = hello_lib.sum_elements(p_pointer, N) # pass in p_pointer or c_array both works +print(f"the sum of the array is {result}") + +import numpy as np +from numpy.ctypeslib import ndpointer + +# 3. Sort (in place float*) +hello_lib.bubble_sort.argtypes = [ndpointer(dtype=np.float32, flags='C_CONTIGUOUS'), ctypes.c_int] +hello_lib.bubble_sort.restype = None +arr = np.array([3.0, 2.3, 4.2, 1.9, 3.2, 1.7], dtype=np.float32) +hello_lib.bubble_sort(arr, len(arr)) +print(arr) + +# 4. Create (int, float -> float*) +a = 0.523 +N = 6 +hello_lib.generate_sine_values.argtypes = [ctypes.c_float, ctypes.c_int] +hello_lib.generate_sine_values.restype = ndpointer(dtype=np.float32, shape=(N,)) +result_arr = hello_lib.generate_sine_values(a, N) +print(type(result_arr)) +print(result_arr) \ No newline at end of file diff --git a/calling-c/hello.c b/calling-c/hello.c new file mode 100644 index 0000000..bcacdb1 --- /dev/null +++ b/calling-c/hello.c @@ -0,0 +1,34 @@ +#include +#include + +int square(int x) { + return x*x; +} + +int sum_elements(int *p, int N) { + int sum = 0; + for (int i = 0; i < N; i++) { + sum += p[i]; + } + return sum; +} + +void bubble_sort(float *p, int N){ + for (int i=0;ip[j+1]){ + float temp = p[j]; + p[j] = p[j+1]; + p[j+1] = temp; + } + } + } +} + +float *generate_sine_values(float a, int N) { + float *result = malloc(N * sizeof(float)); + for (int k = 0; k < N; ++k) { + result[k] = sin(k * a); + } + return result; +} \ No newline at end of file diff --git a/calling-c/hello.o b/calling-c/hello.o new file mode 100644 index 0000000000000000000000000000000000000000..65e4b51dfefa5a6e1c522bce30fda5fa19b9fd26 GIT binary patch literal 2144 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 QHR8AKaS0{jvGDT$2ey6)&;S4c literal 0 HcmV?d00001 diff --git a/calling-cpp/Makefile b/calling-cpp/Makefile new file mode 100644 index 0000000..5098a8d --- /dev/null +++ b/calling-cpp/Makefile @@ -0,0 +1,8 @@ +callee.o: workload.cpp workload.h + g++ -c workload.cpp -o callee.o + +callee.so: callee.o + g++ -shared -o callee.so callee.o + +clean: + rm callee.o callee.so \ No newline at end of file diff --git a/calling-cpp/callee.o b/calling-cpp/callee.o new file mode 100644 index 0000000000000000000000000000000000000000..6b41d0cee12aaa25e57621f385ecd7d5bb42e174 GIT binary patch literal 1560 zcmb_aL2DCH5PmPMP1Uwm5eZafPoiKSNid+TNF;3gQ0YM_cqy_;S5ulz!tMqWA@&dz zgBPz}{0m-t4D=AZdGMeYZ^A-6#FIgUI`i_T*{%UW{NU}(d^6w7W8UtVcUEGYGXiHf z*eD{Fu}`s)pH*&_&9WJ`F56#ayBWwbGnLPd@|Qf4|38bGaqs;_BM^B_ov)DUmYL$#f=pC7nS%U=of2=Lj4qV==}%$k7gX zBt8u}1b=du@%lVpn2ArnhT^lp;X&NP&&|2{7qQ&zRBR0@hPms=18(EzAitvWNR0#D zW0HN}AD5drxaBB22kxm5ukHfe8O>9y?trq#6?eN-u{K4aT4h^a)!lMz=G7eKc&vdn z0Nlw0oL~Dx7~muDl|#P<%OVLNp5`&(H5}i{gZ15^Et2QjB}@2r-DhIc@+~Ivp2tL? z;y890xN^m}1-#9o=Uats9X~49MAfZSZP#xwp*q;b2M=8fZvQ`EKoi{kRHRu}$8RG% z{Vzl>fP*{B5}~c3mzB`*F|eqGUqpfU3lJfXI}hVaI0*UC`IjMwJ^xjo0xkAT!U==s z)4xtRnoo8K668}2+MnSduH-I1a zephuvnvd^?TGG?|jhl_5Uh4UE3;@UB;2TBtM>P-TF!X%mF#E@@PeMNW_9!W8ed#ay E--;fbCjbBd literal 0 HcmV?d00001 diff --git a/calling-cpp/callee.so b/calling-cpp/callee.so new file mode 100644 index 0000000000000000000000000000000000000000..6711d2464962bfa6a1218ac5399797b377c66b2d GIT binary patch literal 14912 zcmeHOTWl0n7(UyAEOOauAR?%&1{1suv{0gw%9gTa&~g#l2cu-N-Q9LKc6XcIDHjv8 zrl>TCQD2Y;ed3{B;^o1_n3xo61dW=S7_ISz2aT%`DH^r6T{#dc(CqHHIKH-)Kcv`Yua>4FEiU$ z0ab%9^BCGBGW5W=WfDN>S*^#5`f*eMUlTR3ns)`+PTk=2`hRrvA-%JA@a^BV>#N#CZ1; zkMnZ54TpKBj5pJ9xKs8UDCyPtjM89y&TQV+Mdw{;l;;9_T|j2rBKofv|DV6FZ!AWx ze|p`!O@pIvy&OJ!^vD}zQal{Tws{HvAXZacG;yf8xnw`sj zFUWr3^NP=jlKmc+&m;72N`P?8CqfVT)COPA$C{4?+IW>-PC;#&sM7Pfgm$`0kI#g* z#e9!B1UQF$joF$Em<*T~HdW8;zL=NWFfU=L5)Cw|&spO~t*Lm%3oUvL*ufVcz*d#8IM%QsE)dA@@! zU1U}RYr5>AmOAd*!{50J?87bVNbnX5xNbm*}u3_FZV zkOu=Y*I;s+??a^^bAiYsGS0Okqb_rq$n+?u+fqT)XY%tOH`sr@;1#q&iYienIW98S zXL4I9@|C`*jtkBcTp}oLsw{PxsNsYi&#zpU$?X~+)D9UK`jJ__0rMOYKPpDm4e{uu zt)BlO@uxS)T1KAfF;>g2*#8h2^OSJ^8K7Q0IN-WKz3k?;w!5P%slxh}Xk)Y0Xf;Ng zRyQ@TUfaZFyMNPozh|lQUM-he`i0t&w$Y0jHBa0s{)cLBd*f*@r|Qtjm6$^ilc` zw%17!4Jt`~Zw9^ETPQxHwvfL_aL86n_a&Ghz5YH|Svp&mo8Cu#oj)s`ae9i0 zT-wQ`hy%&@bP~m4f~Lft=u^N%E}Nv$3KWAjmJXasxCv!-mrBY?7IL|C-mP)q|DlT4 zU0%De-p%wo6NJUO2AMxs)%=-$ZvuZ=&LFB*>itG*8^+gPB(hZ&x|QMyUT}Q=u8-Gp z@Uh+lM}*JIbcp`J$2!d4CGt?<tx&pQ{_q24$ja9O z$haN=qdvXz8xzc5)M_tvI5zmW{!~yLF+TX%|Hp;DQT%W{1HzB_d<_ip50j2_g6nN% z9hLPI*L8By4fBBfBz3C!QQ=h(j)GXGfzJi_F);vp0|yK|ggqMIsV3iJ3XXz7{$H_J BPlo^i literal 0 HcmV?d00001 diff --git a/calling-cpp/caller.py b/calling-cpp/caller.py new file mode 100644 index 0000000..37d7c44 --- /dev/null +++ b/calling-cpp/caller.py @@ -0,0 +1,10 @@ +import ctypes +from ctypes import c_int64 + +my_lib = ctypes.CDLL('./callee.so') + +my_lib.sumprimes.argtypes = [ctypes.c_int64] +my_lib.sumprimes.restype = ctypes.c_int64 +x = input("input x:") +result = my_lib.sumprimes(int(x)) +print(result) \ No newline at end of file diff --git a/calling-cpp/workload.cpp b/calling-cpp/workload.cpp new file mode 100644 index 0000000..3f90eeb --- /dev/null +++ b/calling-cpp/workload.cpp @@ -0,0 +1,21 @@ +#include "workload.h" + +bool isprime(long long x){ + if (x < 2) return false; + for (long long i = 2; i*i <= x ; i++) { + if (x % i == 0) { + return false; + } + } + return true; +} + +long long sumprimes(long long bound){ + long long total = 0; + for (long long i = 1; i <= bound; i++){ + if (isprime(i)) { + total += i; + } + } + return total; +} \ No newline at end of file diff --git a/calling-cpp/workload.h b/calling-cpp/workload.h new file mode 100644 index 0000000..89d3db1 --- /dev/null +++ b/calling-cpp/workload.h @@ -0,0 +1,4 @@ +extern "C"{ + bool isprime(long long); + long long sumprimes(long long); +} \ No newline at end of file