Documente Academic
Documente Profesional
Documente Cultură
Fundamentele Programarii
PYTHON
Observatie: msvcrt este biblioteca C standard MS care conține cele mai multe
funcții C standard și folosește convenția de apelare cdecl
print (windll.kernel32)
from ctypes import *
print(cdll.msvcrt)
Exemple:
1) cdll.LoadLibrary("libc.so.6")
2) libc = CDLL("libc.so.6")
Accesarea funcțiilor din fișierele încărcate
libc.printf
cdll.kernel32[1]
Funcții de apelare
Puteți apela aceste funcții ca orice alt Python apelabil. Acest exemplu folosește
funcția time (), care returnează timpul sistemului în câteva secunde de la epoca
Unix, și funcția GetModuleHandleA (), care returnează un “mâner” al
modulului win32.
print(libc.time(None))
Observtie: ValueError este ridicat atunci când apelați o funcție stdcall cu
convenția de apelare cdecl sau invers
cdll.kernel32.GetModuleHandleA(None)
windll.kernel32.GetModuleHandleA(32)
Constructorul acceptă orice obiect cu valoare de adevăr.
Toate aceste tipuri pot fi create prin apelarea lor cu un inițializator opțional
de tipul și valoarea corectă:
c_int()
c_long(0)
i = c_int(42)
print(i)
Alocarea unei noi valori instanțelor tipurilor de pointer c_char_p, c_wchar_p
și c_void_p schimbă locația de memorie către care indică, nu conținutul
blocului de memorie
s = "Hello, World"
c_s = c_wchar_p(s)
print (c_s)
class Bottles:
def __init__(self, number):
self._as_parameter_ = number
bottles = Bottles(42)
printf(b"%d bottles of beer\n", bottles)
Specificarea tipurilor de argumente necesare (prototipuri de funcții)
printf(b"%d %d %d", 1, 2, 3)
Tipuri de date -returnate
strchr = libc.strchr
strchr(b"abcdef", ord("d"))
Dacă doriți să evitați apelurile ord ("x") de mai sus, puteți seta atributul
argtypes, iar cel de-al doilea argument va fi convertit dintr-un singur
caracter de bytes Python în caractere C char:
strchr.restype = c_char_p
strchr.argtypes = [c_char_p, c_char]
strchr(b"abcdef", b"d")
ctypes exportă funcția byref () care este utilizată pentru a trece parametrii prin
referință. Același efect poate fi obținut cu funcția pointer (), deși pointer ()
face mult mai multă muncă deoarece construiește un obiect pointer real, deci
este mai rapid să îl utilizați byref () dacă nu aveți nevoie de obiectul pointer în
Python în sine:
i = c_int()
f = c_float()
s = create_string_buffer(b'\000' * 32)
print(i.value, f.value, repr(s.value))
Structuri și uniuni
Tipul de câmp trebuie să fie un tip de tipuri cum ar fi c_int, sau orice alt tip
derivat de tipuri: structură, uniune, tablou, pointer.
from ctypes import *
class POINT(Structure):
_fields_ = [("x", c_int),
("y", c_int)]
point = POINT(10, 20)
print(point.x, point.y)
class RECT(Structure):
_fields_ = [("upperleft", POINT), ("lowerright", POINT)]
rc = RECT(point)
print(rc.upperleft.x, rc.upperleft.y)
Structurile cuibate pot fi, de asemenea, inițializate în constructor în mai
multe moduri
Descriptorii de câmp pot fi preluați din clasă, sunt utili pentru depanare,
deoarece pot oferi informații utile:
print(POINT.x)
class Int(Structure):
_fields_ = [("first_16", c_int, 16), ("second_16", c_int, 16)]
print(Int.first_16)
Arrays
Schițele sunt secvențe, care conțin un număr fix de instanțe de același tip.
Modul recomandat de a crea tipuri de matrice este prin înmulțirea unui tip
de date cu un număr întreg pozitiv:
TenPointsArrayType = POINT * 10
Pointeri
Instanțele pointer sunt create prin apelarea funcției pointer () pe un tip ctypes:
pi.contents
pi.contents is I
Raspuns: False
pi.contents is pi.contents
Raspuns: False
Alocarea unei alte instanțe c_int la atributul conținutului pointerului ar
determina indicatorul să indice locația de memorie în care este stocată:
i = c_int(99)
pi.contents = I
pi.contents
print(i)
Raspuns : c_long(99)
pi[0] = 22
print(i)
Raspuns : c_long(22)
conversiile
De obicei, tipurile efectuează verificări stricte de tip. Aceasta înseamnă că, dacă
aveți POINTER (c_int) în lista argtypes a unei funcții sau ca tip de câmp membru
într-o definiție a structurii, sunt acceptate doar cazuri de același tip. Există câteva
excepții de la această regulă, în cazul în care tipurile acceptă alte obiecte.
class Bar(Structure):
_fields_ = [("count", c_int), ("values", POINTER(c_int))]
bar = Bar()
bar.values = (c_int * 3)(1, 2, 3)
bar.count = 3
for i in range(bar.count):
print(bar.values[i])
Raspuns:
1
2
3
Tipurile incomplete sunt structuri, uniuni sau tablouri ai căror membri nu sunt
încă specificați. În C, acestea sunt specificate prin declarații forward, care sunt
definite ulterior:
struct cell {
char *name;
struct cell *next;
};
Funcții callback
În primul rând, trebuie să creați o clasă pentru funcția de apelare inversă. Clasa
cunoaște convenția de apelare, tipul de retur și numărul și tipurile de argumente
pe care le va primi această funcție.
Ambele funcții din fabrică sunt apelate cu tipul de rezultat ca prim argument, iar
funcțiile de retragere funcționează tipurile de argumente preconizate ca
argumente rămase.
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
qsort = libc.qsort
qsort.restype = None