10.2. Performance CTypes¶
10.2.1. Workflow¶
Code:
long factorial(long n) {
if (n == 0)
return 1;
return (n * factorial(n - 1));
}
Build:
$ INCLUDES='-I/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/include/python3.7m/'
$ FILE='mylibrary'
$ gcc -fPIC -c -o ${FILE}.o ${FILE}.c ${INCLUDE}
$ gcc -shared ${FILE}.o -o ${FILE}.so
Run:
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.factorial(16) # 2004189184
lib.factorial(17) # -288522240
10.2.2. Arguments¶
ctypes.c_double
ctypes.c_int
ctypes.c_char
ctypes.c_char_p
ctypes.POINTER(ctypes.c_double)
lib.myfunction.argtypes = [
ctypes.c_char_p,
ctypes.c_int,
ctypes.POINTER(ctypes.c_double),
]
lib.myfunction.restype = ctypes.c_char_p
10.2.3. Multi OS code¶
import sys
import ctypes
if sys.platform == 'darwin':
lib = ctypes.CDLL('/usr/lib/libc.dylib')
elif sys.platform == 'win32':
lib = ctypes.CDLL('/usr/lib/libc.dll')
else:
lib = ctypes.CDLL('/usr/lib/libc.so')
lib.printf("I'm C printf() function called from Python")
import ctypes
lib = ctypes.CDLL('mylibrary.so')
print(dir(lib))
10.2.4. Overflow¶
#include <stdio.h>
void echo(int number) {
printf("Number: %d", number);
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.echo(10 ** 10) # Number: 1410065408
lib.echo(10 ** 30)
# Traceback (most recent call last):
# ctypes.ArgumentError: argument 1: <class 'OverflowError'>: int too long to convert
10.2.5. Use Case - 0x01¶
#include <stdio.h>
void ehlo() {
printf("Ehlo World");
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.ehlo()
10.2.6. Use Case - 0x02¶
#include <stdio.h>
void greeting(char *name) {
printf("Ehlo %s!\n", name);
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.greeting.argtypes = [ctypes.c_char_p]
name = ctypes.create_string_buffer('Watney'.encode('ASCII'))
lib.greeting(name)
10.2.7. Use Case - 0x03¶
#include <stdio.h>
void number(int num) {
printf("My number %d\n", num);
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.number(10)
10.2.8. Use Case - 0x04¶
int return_int(int num) {
return num;
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
i = lib.return_int(15)
print(i)
10.2.9. Assignments¶
"""
* Assignment: C Types
* Complexity: easy
* Lines of code: 10 lines
* Time: 13 min
English:
1. Using C Types print date and time, using function defined in C `<time.h>`
2. Run doctests - all must succeed
Polish:
1. Wykorzystując C Types wypisz datę i czas, za pomocą funkcji zdefiniowanej w C `<time.h>`
2. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
TODO: Doctests
"""