Python Academy · Oppitunti

ctypes: C-kirjastojen kutsuminen Pythonista

Ladatkaa jaettuja kirjastoja ja kutsukaa C-funktioita ctypesillä.

Oppitunti 2/413 vaihetta

ctypes: C-kirjastojen kutsuminen Pythonista on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mikä on ctypes?

ctypes on vakiokirjaston moduuli, jolla jaettuja C-kirjastoja ladataan ja niiden funktioita kutsutaan Pythonista — kääntämistä ei tarvita.

import ctypes

# Load the C standard library
libc = ctypes.CDLL("libc.so.6")   # Linux
# libc = ctypes.CDLL("libSystem.dylib")  # macOS

libc.puts(b"Hello from C!")

Kirjastojen lataaminen

Käyttäkää ctypes.CDLL-luokkaa cdecl-kutsukäytäntöön (useimmat C-kirjastot) ja WinDLL-luokkaa Windowsin stdcall-rajapintoihin.

import ctypes

# Platform-independent approach:
import ctypes.util
libm_name = ctypes.util.find_library("m")
libm = ctypes.CDLL(libm_name)

result = libm.sqrt
result.restype = ctypes.c_double
result.argtypes = [ctypes.c_double]
print(result(2.0))   # 1.4142...

C-tietotyypit

Yhdistäkää Pythonin tyypit C-tyyppeihin ctypes-luokkien avulla: c_int, c_double, c_char_p, c_void_p ja niin edelleen.

import ctypes

x = ctypes.c_int(42)
print(x.value)   # 42

d = ctypes.c_double(3.14)
print(d.value)   # 3.14

s = ctypes.c_char_p(b"hello")
print(s.value)   # b"hello"

argtypes- ja restype-määritteiden asettaminen

Ilmoittakaa aina argtypes (parametrien tyypit) ja restype (palautustyyppi), jotta tyyppien yhteensopimattomuus ei aiheuta huomaamattomia kaatumisia.

import ctypes, ctypes.util

libm = ctypes.CDLL(ctypes.util.find_library("m"))

libm.pow.argtypes = [ctypes.c_double, ctypes.c_double]
libm.pow.restype  = ctypes.c_double

print(libm.pow(2.0, 10.0))   # 1024.0

Osoittimien välittäminen

Käyttäkää ctypes.byref(var)- tai ctypes.pointer(var)-kutsua välittääksenne osoittimen C-muuttujaan.

import ctypes

libc = ctypes.CDLL(None)   # None = current process

value = ctypes.c_int(0)
# Passing pointer to C function:
# libc.some_func(ctypes.byref(value))
print(value.value)

Rakenteet

Määritelkää C-rakenteet perimällä ctypes.Structure ja luettelemalla _fields_-kentät.

import ctypes

class Point(ctypes.Structure):
    _fields_ = [
        ("x", ctypes.c_double),
        ("y", ctypes.c_double),
    ]

p = Point(1.0, 2.0)
print(p.x, p.y)   # 1.0 2.0

Taulukot

Luokaa C-taulukoita lausekkeella TypeClass * N.

import ctypes

IntArray5 = ctypes.c_int * 5
arr = IntArray5(10, 20, 30, 40, 50)
for v in arr:
    print(v, end=" ")   # 10 20 30 40 50

Takaisinkutsut (funktio-osoittimet)

Käyttäkää ctypes.CFUNCTYPE-kutsua luodaksenne C:n kutsuttavissa olevan Python-funktion, jonka voitte välittää takaisinkutsuna.

import ctypes

CompareFunc = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)

def my_compare(a, b):
    return a - b

c_compare = CompareFunc(my_compare)
# Pass c_compare to a C function expecting a comparator

Windowsin DLL-tiedostojen lataaminen

Käyttäkää Windowsissa ctypes.WinDLL-luokkaa stdcall-kutsukäytäntöä käyttäville DLL-tiedostoille, kuten Windows API:lle.

import ctypes   # Windows only

kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
kernel32.GetTickCount.restype = ctypes.c_ulong
print(kernel32.GetTickCount())

Virheenkäsittely

Tarkistakaa ctypes.get_last_error() Windowsissa tai käyttäkää Python-tason try/except-rakennetta virheille, jotka palautetaan erityisinä arvoina.

import ctypes

# Many C functions return -1 or NULL on error:
result = some_c_function()
if result == -1:
    raise OSError("C function failed")

# For errno on POSIX:
import os
if result < 0:
    raise OSError(os.strerror(ctypes.get_errno()))

Käytännön esimerkki: SHA-256 OpenSSL:llä

Kutsukaa OpenSSL:n SHA256-funktiota suoraan ctypesin avulla ilman Python-sidontakirjastoa.

import ctypes, ctypes.util

libcrypto = ctypes.CDLL(ctypes.util.find_library("crypto"))

SHA256 = libcrypto.SHA256
SHA256.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p]
SHA256.restype  = ctypes.c_char_p

buf = ctypes.create_string_buffer(32)
SHA256(b"hello", 5, buf)
print(buf.raw.hex())

Pikatarkistus

Miksi ctypes-funktiolle pitäisi aina asettaa argtypes ja restype?

Kertaus

ctypes lataa jaettuja C-kirjastoja ilman kääntämistä. Ilmoittakaa argtypes ja restype jokaiselle funktiolle. Käyttäkää Structure-luokkaa C-rakenteille, TypeClass * N-lauseketta taulukoille ja CFUNCTYPE-luokkaa takaisinkutsuille.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”ctypes: C-kirjastojen kutsuminen Pythonista” ilmainen?

Kyllä – oppitunnin ”ctypes: C-kirjastojen kutsuminen Pythonista” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”ctypes: C-kirjastojen kutsuminen Pythonista”?

Ladatkaa jaettuja kirjastoja ja kutsukaa C-funktioita ctypesillä. Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”ctypes: C-kirjastojen kutsuminen Pythonista”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Miksi C-laajennuksia käytetään? Käyttötapaukset ja kompromissit
  2. ctypes: C-kirjastojen kutsuminen Pythonista
  3. cffi: C:n vierasfunktiorajapinta
  4. Pythonin C-laajennusmoduulin kirjoittaminen
← Takaisin: Python Academy