Topic: [risolto]ctypes in Python3  (Letto 351 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 297
  • Punti reputazione: 0
    • Mostra profilo
[risolto]ctypes in Python3
« il: Luglio 27, 2018, 19:47 »
Ho un codice piuttosto semplice:


from ctypes import *

FL_lib = cdll.LoadLibrary("./lib.so")

class struct(Structure):
    _fields_ = [
        ("var1", c_char * 7),
        ("var2", c_char * 11),
        ("var3", c_int)
    ]

FL_sol = FL_lib.solver
FL_sol.restype = struct

init = FL_sol("parametro...")
print(init.var1, init.var2, init.var3)


Su python2 funziona, su python 3 no.

Come lo devo modificare per aggiornare lo script, che sarebbe anche ora?
« Ultima modifica: Luglio 28, 2018, 13:50 da tommyb1992 »

Offline Markon

  • python sapiens sapiens
  • *
  • moderatore
  • Post: 4.104
  • Punti reputazione: 5
    • Mostra profilo
    • Neolithic
Re:ctypes in Python3
« Risposta #1 il: Luglio 27, 2018, 21:06 »
Ciao,

Potresti spiegare perche' non funziona? Tipo il messaggio di errore che ottieni, ecc.

Dai, proviamo a seguire le linee guida :)

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 2.854
  • Punti reputazione: 9
    • Mostra profilo
Re:ctypes in Python3
« Risposta #2 il: Luglio 27, 2018, 21:32 »
> Su python2 funziona, su python 3 no.

La meraviglia è che funziona in python 2.
Che cosa dovrebbe singnificare quello "struct" alla linea 13?

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 297
  • Punti reputazione: 0
    • Mostra profilo
Re:ctypes in Python3
« Risposta #3 il: Luglio 28, 2018, 10:22 »
Ciao,

Potresti spiegare perche' non funziona? Tipo il messaggio di errore che ottieni, ecc.

Dai, proviamo a seguire le linee guida :)

from ctypes import *


FL_lib = cdll.LoadLibrary("./lib.so")


class FL_struct(Structure):
    _fields_ = [
        ("var1", c_char * 7),
        ("var2", c_char * 11),
        ("value", c_int * 3),
    ]

FL_solver = FL_lib.solver
FL_solver.restype = FL_struct


if __name__ == "__main__":
    def checkFL():
        sol = FL_solver("argomento...")
        print("Var1:", sol.var1)
        print("Var2:", sol.var2)
        print("Value:", sol.value[0], sol.value[1], sol.value[2])

    checkFL()



tomas@tomas-desktop:~/Desktop/Delilah.AI/cgi-bin$ python2 wrapper.py
('Var1:', '....')
('Var2:', '...')
('Value:', 1, 1, 2)



<------- risultati giusti (ho messo i 3 puntini, ma non è importante, sono campi di tipo char e sono quelli giusti, compresi gli int[])

tomas@tomas-desktop:~/Desktop/Delilah.AI/cgi-bin$ python3 wrapper.py
First test: b''
Second test: b''
Value: 3, 7, 7



<------- risultati sbagliati. Gli interi non centrano un'acca e i valori di ritorno stringa sono quelli che l'output stampa.

Citazione
Che cosa dovrebbe singnificare quello "struct" alla linea 13?
L'assegnazione dei tipi dei valori di ritorno
« Ultima modifica: Luglio 28, 2018, 10:25 da tommyb1992 »

Offline Markon

  • python sapiens sapiens
  • *
  • moderatore
  • Post: 4.104
  • Punti reputazione: 5
    • Mostra profilo
    • Neolithic
Re:ctypes in Python3
« Risposta #4 il: Luglio 28, 2018, 11:49 »
Com'e' che l'output di python2 differisce da quello di python3?

('Var1:', '....') != First test: b''

Nel codice non vedo alcun "first test".

Al di la' di questo, che potrebbe essere una semplice modifica non riportata nel codice, acusa, ma ancora non e' chiaro. Dove avviene l'assegnazione dei var1, var2 e value? Immagino in lib.so? Se e' cosi', e' piuttosto difficile fare il debugging.

Questo genere di errori puoi analizzarlo tramite un debugger tipo pdb++ (o pycharm con debugger). Lo installi, setti i breakpoints e cerchi di capire dove avviene cosa. I vantaggi che ottieni sono molteplici:
1) diventi un programmatore migliore
2) parti da un problema e arrivi a una soluzione da solo, imparando di piu' (capisci anche quali chiamate vengono fatte in sequenza, ecc)
3) perdi meno tempo, dato che sul forum devi aspettare qualcuno disposto ad aiutarti e, come vedi, questo ping/pong dura da un po'
4) non passi per quello che vuole la pappa pronta
« Ultima modifica: Luglio 28, 2018, 11:53 da Markon »

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 297
  • Punti reputazione: 0
    • Mostra profilo
Re:ctypes in Python3
« Risposta #5 il: Luglio 28, 2018, 13:47 »
Ok ho provato a fare una cosa molto semplice:

test.c
test.py


tomas@tomas-desktop:~/Desktop/Misc$ gcc test.c -o output
tomas@tomas-desktop:~/Desktop/Misc$ ./output
Parametro passato come argomento: Prova
var1: ab
var2: 1 2 3
var3: 100

tomas@tomas-desktop:~/Desktop/Misc$ gcc test.c -fPIC -shared -o output.o
tomas@tomas-desktop:~/Desktop/Misc$ python3 test.py
Parametro passato come argomento: s
b'ab'
1 2 3
100


E funziona...

ho ricompilato il mio programma originale (quello che non funzionava su python3) e ora funziona su python3...

Onestamente non so come sia possibile e cosa sia accaduto, ho compilato su una versione differente della stessa distro quel file non più di 6 mesi fa.
Però vabbè... risolto.

Grazie a tutti

===============
EDIT

aggiungo che in python 3 bisogna passare gli argomenti con encode() altrimenti prende solo il primo carattere:


tmp = FL_solver("stampami") # <--- sbagliato
tmp = FL_solver("stampami".encode()) # <--- giusto
« Ultima modifica: Luglio 30, 2018, 11:16 da tommyb1992 »