5. C Types

5.1. Code

long factorial(long n) {
    if (n == 0)
        return 1;

    return (n * factorial(n - 1));
}

5.2. Build

$ INCLUDES='-I/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/include/python3.7m/'
$ FILE='mylib-ctypes'
$ gcc -fPIC -c -o ${FILE}.o ${FILE}.c ${INCLUDE}
$ gcc -shared ${FILE}.o -o ${FILE}.so

5.3. Run

import ctypes

lib = ctypes.CDLL('mylib.so')

lib.factorial(16)  # 2004189184
lib.factorial(17)  # -288522240

5.3.1. Argumenty

  • ctypes.c_double

  • ctypes.c_int

  • ctypes.c_char

  • ctypes.c_char_p

  • ctypes.POINTER(ctypes.c_double)

lib.my_function.argtypes = [
    ctypes.c_char_p,
    ctypes.c_int,
    ctypes.POINTER(ctypes.c_double),
]
lib.my_function.restype = ctypes.c_char_p

5.4. Use cases

#include <stdio.h>

void ehlo() {
    printf("Ehlo World");
}

void greeting(char *name) {
    printf("Ehlo %s!\n", name);
}

void number(int num) {
    printf("My number %d\n", num);
}

int return_int(int num) {
    return num;
}
import ctypes

lib = ctypes.CDLL('mylib-ctypes.so')

lib.ehlo()

lib.greeting.argtypes = [ctypes.c_char_p]
name = ctypes.create_string_buffer('Twardowski'.encode('ASCII'))
lib.greeting(name)

lib.number(10)

print(dir(lib))

i = lib.return_int(15)
print(i)

5.4.1. 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")

5.4.2. Overflow

#include <stdio.h>

void wypisz_liczbe(int liczba) {
    printf("Liczba to: %d", liczba);
}
import ctypes

lib = ctypes.CDLL('biblioteka.so')

lib.wypisz_liczbe(10 ** 10)  # Liczba to: 1410065408

lib.wypisz_liczbe(10 ** 30)
# Traceback (most recent call last):
#   ...
# ctypes.ArgumentError: argument 1: <class 'OverflowError'>: int too long to convert

5.5. Assignments

5.5.1. C Types

Wykorzystując C Types wyświetl na ekranie datę i czas, za pomocą funkcji zdefiniowanej w C <time.h>