8.6. C Types¶
8.6.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
8.6.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
8.6.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))
8.6.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
8.6.5. Use Case - 1¶
#include <stdio.h>
void ehlo() {
printf("Ehlo World");
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.ehlo()
8.6.6. Use Case - 2¶
#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('Twardowski'.encode('ASCII'))
lib.greeting(name)
8.6.7. Use Case - 3¶
#include <stdio.h>
void number(int num) {
printf("My number %d\n", num);
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
lib.number(10)
8.6.8. Use Case - 4¶
int return_int(int num) {
return num;
}
import ctypes
lib = ctypes.CDLL('mylibrary.so')
i = lib.return_int(15)
print(i)