Chiamare una funzione in C da Python

Peri

Nuovo Utente
82
3
Salve, stavo sperimentando il multilinguaggio su Python, però ho avuto una serie di problemi con un programma corto corto che mi serviva per capire meglio un dettaglio.
La funzione in C ammette come input un array e parametri relativi alla sua dimensione:
C:
int synthex(int pixels[][3], int width, int height)
{
    return pixels[0][0];
}
Niente di speciale, semplicemente prende in input una matrice e ne legge il valore scritto in 0,0
Ora devo chiamare questa funzione, creo il file .so (sto su Linux) e poi eseguo il seguente codice:
Python:
import thesis as th

if __name__ == '__main__':
    th.synthesis('./Data/cibo/pancake.jpg')
Dove la funzione chiamata sarà:
Python:
from PIL import Image
import ctypes as c

Cshared = c.CDLL("./Csource/shared.so")
pixel_t = c.c_ubyte * 3

def synthesis(image_dir: str):
    """Sintex call a C program."""
    img = Image.open(image_dir)
    
    pixels = list(img.getdata())
    width, height = img.size
    
    pixelsArray = [pixel_t(0, 0, 0) for _ in range(len(pixels))]
    pixels_t = pixel_t * len(pixels)
    c_pixels = pixels_t(*pixelsArray)
    
    # call C function
    ret = Cshared.synthex(c_pixels, width, height, image_dir)
    print('image: ' + image_dir + ' > ret: ', ret)

Vorrei quindi leggere letteralmente il primo pixel
Solo che la funzione mi restituisce 0 (quindi scrive image: ./Data/cibo/pancake.jpg > ret: 0 )quando invece il l'immagine non è nera (ho provato a testarlo anche su immagini diverse ma niente...)
Infatti il primo pixel (leggendo pixels) ha un colore tipo bianco.
Probabilmente sarà una boiata, ma sto cercando di imparare come si fa e non ne esco. Quindi se avete modo ci starebbe anche una spiegazione della soluzione o degli errori.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Premesso che sto per andare a dormire, e sto leggendo da smartphone...

Non conosco Python quindi magari dirò una stupidaggine. Dove utilizzi "pixels"? Vedo che richiami getData, quindi presumo ci siano i pxs dell'immagine.

Non vedo però il suo utilizzo, mi viene da pensare che crei un Array inizializzato con tutti i canali a 0.

Domani da PC se ho un po' di tempo provo.
 

bigendian

Utente Attivo
749
432
OS
Linux
Mi sa che gli stai passando porcheria. Fatti un array hardcoded in python e passaglielo, e verifica che sia corretto in C con un printf.
 

Peri

Nuovo Utente
82
3
Premesso che sto per andare a dormire, e sto leggendo da smartphone...

Non conosco Python quindi magari dirò una stupidaggine. Dove utilizzi "pixels"? Vedo che richiami getData, quindi presumo ci siano i pxs dell'immagine.

Non vedo però il suo utilizzo, mi viene da pensare che crei un Array inizializzato con tutti i canali a 0.

Domani da PC se ho un po' di tempo provo.
Ah cavolo, probabilmente dici giusto. Oggi pomeriggio provo a rimediare
Ad occhio invece di dire pixel_t(0,0,0) for _ in range(len(pixels)) dovrei scrivere pixel_t(c) for c in pixels
Potrebbe funzionare?
Post unito automaticamente:

Mi sa che gli stai passando porcheria. Fatti un array hardcoded in python e passaglielo, e verifica che sia corretto in C con un printf.
Avevo escluso a priori la possibilità che printf potesse funzionare (pensavo "chissà dove scrive sto programma"), ma in effetti potevo tentare 😅
 

bigendian

Utente Attivo
749
432
OS
Linux
forza forza, non ti arrendere per un pixel :) fatti un bicchier di malvasia, che tutti i bachi passano
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!