OVH Cloud OVH Cloud

ctypes et windll

1 réponse
Avatar
Pierre-Eric.Melchy
Bonjour,
Pour une exp=E9rience dans notre labo (physique) nous voulons utiliser
Python afin de g=E9rer les instruments. Aussi nous servons-nous de la
biblioth=E8que GPIB et du module ctypes. Cependant nous obtenons des
r=E9sultats surprenants =E0 notre programme :

from ctypes import *
#print windll.kernel32
wdl=3Dwindll.kopgpib32 # status 256 =3D completed
#wdl=3Dgetattr(windll, "Gpib-32") # status 33024=3D completed + error
detected
# Daten definieren

deviceNumber=3Dc_int(0)
BoardIndex=3Dc_int(0)
PrimaryAdress=3Dc_int(0)
SecondaryAdress=3Dc_int(0)
TimeOutSetting=3Dc_int(11) # 1 s
EOILine=3Dc_int(1)
EOSTermination=3Dc_int(0)

# Fehlercodes iberr
errName =3D {
0:"System error",
1:"Function requires GPIB board to be CIC",
2:"Write function detected no Listeners ",
3:"Interface board not addressed correctly",
4:"Invalid argument to function call",
5:"Function requires GPIB board to be SAC",
6:"I/O operation aborted",
7:"Non-existent interface board",
8:"Error performing DMA",
10:"I/O operation started before previous operation completed",
11:"No capability for intended operation",
12:"File system operation error",
14:"Command error during device call",
15:"Serial poll status byte lost",
16:"SRQ remains asserted",
20:"The return buffer is full",
21:"Address or board is locked"
}

# status
def printStatus(status):
if status & 0x1 :print "DCAS"
if status & 0x2 :print "DTAS"
if status & 0x4 :print "LACS"
if status & 0x8 :print "TACS"
if status & 0x10 :print "AATN"
if status & 0x20 :print "CIC"
if status & 0x40 :print "RREM"
if status & 0x80 :print "LOK"
if status & 0x100 :print "CMPL"
if status & 0x200 :print "SPOLL"
if status & 0x400 :print "EEVENT"
if status & 0x800 :print "RQS"
if status & 0x1000 :print "SRQI"
if status & 0x2000 :print "END"
if status & 0x4000 :print "TIMO"
if status & 0x8000 :print "ERR"




# initialisiere device
deviceNumber=3Dwdl.ibdev(BoardIndex,PrimaryAdress,SecondaryAdress,TimeOutSe=
tting,EOILine,EOSTermination)

print errName[wdl.ThreadIberr()]
printStatus(wdl.ThreadIbsta())

print "deviceNumber: ", deviceNumber

wdl.ibclr(deviceNumber);

wdl.ibwrt(deviceNumber, c_char_p("*IDN?"), c_int(16))

buffer=3Dc_char_p("")
print buffer
wdl.ibwrt(deviceNumber,buffer, c_int(100))
print buffer
#wdl.ibwrt(c_int(32256), c_char_p("*IDN?"), c_int(5))
#wdl.ibrd(c_int(32256),buffer, c_int(100))
#print buffer
#wdl.ibwrt(c_int(32256), c_char_p("*IDN?"), c_int(8))
#wdl.ibrd(c_int(32256),buffer, c_int(100))
#print buffer

# Take the device offline
wdl.ibonl(deviceNumber, c_int(0))

# Take the interface offline
wdl.ibonl(BoardIndex, c_int(0))

Les r=E9sultats sont mis en commentaire ligne 3 et 4, selon l'appel qui
est fait(diff=E9rent alors qu'il s'agit des m=EAmes biblioth=E8ques !).
kopgpib32 est une copie de la biblioth=E8que que nous ne parvenions pas
=E0 appeler la premi=E8re fois.

Par ailleurs les r=E9sultats des autres print sont :
deviceNumber : 32256
c_char_p(=B4=B4)
c_char_p(=B4=B4)


Existe-t-il une biblioth=E8que Python plus adapt=E9e pour notre
utilisation ?

Merci d'avance pour les r=E9ponses ou les pistes.

1 réponse

Avatar
F. Petitjean
Bonjour,
Pour une expérience dans notre labo (physique) nous voulons utiliser
Python afin de gérer les instruments. Aussi nous servons-nous de la
bibliothèque GPIB et du module ctypes. Cependant nous obtenons des
résultats surprenants à notre programme :

from ctypes import *
à éviter, écrivez plutôt

import ctypes
from ctypes import c_int, c_char_p
#print windll.kernel32
wdl=windll.kopgpib32 # status 256 = completed
wdl = ctypes.windll.kopgpib32

#wdl=getattr(windll, "Gpib-32") # status 33024= completed + error
detected
# Daten definieren

deviceNumber=c_int(0)
BoardIndex=c_int(0)
PrimaryAdress=c_int(0)
SecondaryAdress=c_int(0)
TimeOutSetting=c_int(11) # 1 s
EOILine=c_int(1)
EOSTermination=c_int(0)

# Fehlercodes iberr
errName = {
0:"System error",
1:"Function requires GPIB board to be CIC",
2:"Write function detected no Listeners ",
3:"Interface board not addressed correctly",
4:"Invalid argument to function call",
5:"Function requires GPIB board to be SAC",
6:"I/O operation aborted",
7:"Non-existent interface board",
8:"Error performing DMA",
10:"I/O operation started before previous operation completed",
11:"No capability for intended operation",
12:"File system operation error",
14:"Command error during device call",
15:"Serial poll status byte lost",
16:"SRQ remains asserted",
20:"The return buffer is full",
21:"Address or board is locked"
}

# status
def printStatus(status):
if status & 0x1 :print "DCAS"
if status & 0x2 :print "DTAS"
if status & 0x4 :print "LACS"
if status & 0x8 :print "TACS"
if status & 0x10 :print "AATN"
if status & 0x20 :print "CIC"
if status & 0x40 :print "RREM"
if status & 0x80 :print "LOK"
if status & 0x100 :print "CMPL"
if status & 0x200 :print "SPOLL"
if status & 0x400 :print "EEVENT"
if status & 0x800 :print "RQS"
if status & 0x1000 :print "SRQI"
if status & 0x2000 :print "END"
if status & 0x4000 :print "TIMO"
if status & 0x8000 :print "ERR"




# initialisiere device
deviceNumber=wdl.ibdev(BoardIndex,PrimaryAdress,SecondaryAdress,TimeOutSetting,EOILine,EOSTermination)
Pourrait-on avoir le prototype C de ka foction appelée ?

En écrivant sur plusieurs lignes, et en initialisant des attributs
propres à ctypes vous pouvez traduire en Python le prototype :
ibdev = wdl.ibdev
ibdev.restype = c_int # peut-être res_type, je n'ai pas la doc sous
les yeux
ibdev.argtypes = (c_int, ...) # ou arg_types ?
et êtes-vous sûr que tous les paramètres ne servent qu'en entrée ? Aucun
qui ne serait initialisé par ibdev et qui devrait être passé comme
byref(nom) ?

print errName[wdl.ThreadIberr()]
printStatus(wdl.ThreadIbsta())

print "deviceNumber: ", deviceNumber

wdl.ibclr(deviceNumber);

wdl.ibwrt(deviceNumber, c_char_p("*IDN?"), c_int(16))
Avec un argument C char * ou const char *, on ne sait jamais si on a

affaire à une chaîne de caractères ou à un pointeur sur un caractère et
la documentation ctypes est loin d'être claire. Il est vrai que la
sémantique du C qui ne permet que de retourner qu'un scalaire
(directement) n'arrange pas les choses car elle oblige à définir des
interfaces tordues où certains paramètres sont déclarés pointeur (sur
des variables de l'appelant) alors qu'en Python il suffirait de
retourner ces arguments produits par la fonction dans un tuple.

Existe-t-il une bibliothèque Python plus adaptée pour notre
utilisation ?
Je pense que ctypes pourrait faire votre bonheur, tout au moins si la

documentation était à la hauteur. Il serait judicieux de poser la
question sur la liste de diffusion de ctypes (même trouver cette liste
n'est pas évident !) ou bien envoyer un courrier à Yhomas Heller
(j'aurais presqu'envie à votre place d'écrire un message en anglais et
en allemand :-)

Merci d'avance pour les réponses ou les pistes.
Tenez nous au courant des progrès que vous pourriez faire car il n'y a

rien de plus frustrant que de pouvoir charger une bibliothèque dans la
minute et de ne pas pouvoir appeler ses fonctions.