The literal "?*INSTR"
creates an str
object, which is Unicode in Python 3. ctypes converts a unicode string to a wchar_t *
. On Windows, wchar_t
is 2 bytes, so ctypes passes a pointer to the UTF-16 encoded buffer "?\x00*\x00I\x00N\x00S\x00T\x00R\x00"
. Bear in mind that the function expects a null-terminated string.
To pass a byte string instead, prefix the literal with b
to create a bytes
object, i.e. use b"?*INSTR"
.
To prevent a mistake like this from passing unnoticed, define the function pointer's argtypes
. ctypes will raise an ArgumentError
if a unicode str
argument is passed for a parameter that's defined to be c_char_p
.
from ctypes import *
visa = WinDLL("visa32.dll") # or windll.visa32
def vi_status_check(vi_status, func, args):
if vi_status < 0:
raise RuntimeError(hex(vi_status + 2**32))
return args
visa.viOpenDefaultRM.errcheck = vi_status_check
visa.viOpenDefaultRM.argtypes = [POINTER(c_uint32)]
visa.viFindRsrc.errcheck = vi_status_check
visa.viFindRsrc.argtypes = [c_uint32, # sesn
c_char_p, # expr
POINTER(c_uint32), # findList
POINTER(c_uint32), # retcnt
c_char_p] # desc
rm_session = c_uint32()
visa.viOpenDefaultRM(byref(rm_session))
expr = b"?*INSTR"
instr_list = c_uint32()
nb = c_uint32()
desc = create_string_buffer(256)
visa.viFindRsrc(rm_session,
expr,
byref(instr_list),
byref(nb),
desc)
The NI-VISA Programmer Reference Manual says on page 5-30 that instrDesc
should be at least 256 bytes.