1) We are using "ctype" native Python module to load the shared library.
2) The ctype Python module is available starting with Python 2.5. Make sure you have the most recent Python installed on your system
(.env) [boris@fedora33server CPYTHON]$ cat arithmatic.h
void connect();
int randNum();
int multNum(int a, int b);
(.env) [boris@fedora33server CPYTHON]$ cat arithmatic.c
#include <stdio.h>
#include <stdlib.h>
#include "arithmatic.h"
void connect()
{
printf("Connected to C extension\n");
}
//return random value in range of 0-100
int randNum()
{
int nRand = rand() % 100;
return nRand;
}
//Multiply two integer numbers and return value
int multNum(int a, int b)
{
int nMult = a*b;
return nMult;
}
That is supposed to run in one line, otherwise you have to place
"\" to let gcc know that the rest of line would go after cartridge return
(.env) [boris@fedora33server CPYTHON]$ gcc -shared -o libcalci.so -fPIC arithmatic.c
(.env) [boris@fedora33server CPYTHON]$ ll
total 28
-rw-rw-r--. 1 boris boris 291 Jun 18 19:23 arithmatic.c
-rw-rw-r--. 1 boris boris 57 Jun 18 18:34 arithmatic.h
-rwxrwxr-x. 1 boris boris 16280 Jun 18 19:31 libcalci.so
-rw-rw-r--. 1 boris boris 374 Jun 18 19:21 MyTest.py
(.env) [boris@fedora33server CPYTHON]$ cat MyTest.py
from ctypes import *
libCalc = CDLL("./libcalci.so")
#call C function to check connection
libCalc.connect()
#calling randNum() C function
#it returns random number
varRand = libCalc.randNum()
print ("Random Number:", varRand, type(varRand))
#calling multNum() C function
#it returns multiplication of two numbers
varMult = libCalc.multNum(38,27)
print ("Multiplication : ", varMult)
(.env) [boris@fedora33server CPYTHON]$ python MyTest.py
Connected to C extension
Random Number: 83 <class 'int'>
Multiplication : 1026
A bit more complicated sample
(.env) [boris@fedora33server CDEVPY]$ cat sum.c
int our_function(int num_numbers, int *numbers) {
int i;
int sum = 0;
for (i = 0; i < num_numbers; i++) {
sum += numbers[i];
}
return sum;
}
(.env) [boris@fedora33server CDEVPY]$ gcc -fPIC -shared -o libsum.so sum.c
(.env) [boris@fedora33server CDEVPY]$ ll
total 28
-rwxrwxr-x. 1 boris boris 16160 Jun 18 21:35 libsum.so
-rw-rw-r--. 1 boris boris 107 Jun 18 21:33 MyRun.py
-rw-rw-r--. 1 boris boris 169 Jun 18 21:29 sum.c
-rw-rw-r--. 1 boris boris 345 Jun 18 21:29 sum.py
(.env) [boris@fedora33server CDEVPY]$ cat sum.py
import ctypes
_sum = ctypes.CDLL('./libsum.so')
_sum.our_function.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_int))
def our_function(numbers):
global _sum
num_numbers = len(numbers)
array_type = ctypes.c_int * num_numbers
result = _sum.our_function(ctypes.c_int(num_numbers), array_type(*numbers))
return int(result)
(.env) [boris@fedora33server CDEVPY]$ cat MyRun.py
import sum
def main():
print (sum.our_function([11,2,-3,4,-3,6]))
if __name__=="__main__":
main()
(.env) [boris@fedora33server CDEVPY]$ python MyRun.py
17
(.env) [boris@fedora33server CDEVPY]$ ll
total 28
-rwxrwxr-x. 1 boris boris 16160 Jun 18 21:35 libsum.so
-rw-rw-r--. 1 boris boris 107 Jun 18 21:33 MyRun.py
drwxrwxr-x. 2 boris boris 32 Jun 18 21:36 __pycache__
-rw-rw-r--. 1 boris boris 169 Jun 18 21:29 sum.c
-rw-rw-r--. 1 boris boris 345 Jun 18 21:29 sum.py
PyCharm project based ctypes wrapper
Pretty short sample in C++
[boris@fedora33server ]$ ll
total 8
-rw-rw-r--. 1 boris boris 126 Jun 19 08:46 dullmath.cpp
-rw-rw-r--. 1 boris boris 79 Jun 19 08:52 MyProg.py
[boris@fedora33server ]$ cat dullmath.cpp
extern "C" int fibonacci(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
[boris@fedora33server]$ g++ -shared dullmath.cpp -o libdullmath.so
[boris@fedora33server ]$ ll
total 24
-rw-rw-r--. 1 boris boris 126 Jun 19 08:46 dullmath.cpp
-rwxrwxr-x. 1 boris boris 16176 Jun 19 08:52 libdullmath.so
-rw-rw-r--. 1 boris boris 79 Jun 19 08:52 MyProg.py
[boris@fedora33server]$ cat MyProg.py
import ctypes
lib = ctypes.CDLL(f'./libdullmath.so')
print(lib.fibonacci(11))
[boris@fedora33server ]$ python MyProg.py
89
One more sample
[boris@fedora33server ]$ cat function.c
int myFunction(int num)
{
if (num == 0)
// if number is 0, do not perform any operation.
return 0;
else
// if number divides by 11, return 1 else return 0
return (num % 11 == 0 ? 1 : 0) ;
}
[boris@fedora33server ]$ gcc -fPIC -shared -o libfun.so function.c
[boris@fedora33server ]$ ll libfun.so
-rwxrwxr-x. 1 boris boris 16168 Jun 19 10:31 libfun.so
[boris@fedora33server ]$ cat MyProg.py
import ctypes
test_text = input ("Введите число: ")
test_number = int(test_text)
# libfun loaded to the python file
# using fun.myFunction(),
# C function can be accessed
# but type of argument is the problem.
fun = ctypes.CDLL("./libfun.so")
# Now whenever argument
# will be passed to the function
# ctypes will check it.
fun.myFunction.argtypes = [ctypes.c_int]
returnVale = fun.myFunction(test_number)
print(returnVale)
[boris@fedora33server ]$ python MyProg.py
Введите число: 121
1
[boris@fedora33server ]$ python MyProg.py
Введите число: 555
0
[boris@fedora33server ]$ python MyProg.py
Введите число: 550
1
REFERENCES
No comments:
Post a Comment