Использование NI-VISA с Python: код ошибки -1073807343 в viFindRsrc
Я работаю в Python и установил последнюю версию NI-VISA. Я использую пакет ctypes для загрузки файла visa32.dll, установленного вместе с NI-VISA.
Я использовал как документацию NI-VISA, так и следующую страницу в качестве основы для своего кода.
Я уже знаю обертку pyVisa и с помощью их функции find_resources возвращает подключенные инструменты. Тем не менее, я не хочу использовать эту оболочку и предпочел бы использовать файл VISA DLL напрямую.
Я также просматривал код pyVisa, чтобы увидеть, как они это делают, и пытался извлечь уроки из этого, но, похоже, я до сих пор не понимаю.
Вот мой текущий незаконченный код:
import sys
from ctypes import *
visa = windll.LoadLibrary("visa32.dll")
resourceManagerHandle = c_int(0)
visa.viOpenDefaultRM(byref(resourceManagerHandle))
instr_list = c_ulong(0)
nb = c_ulong(0)
desc = create_string_buffer(128)
print(visa.viFindRsrc(resourceManagerHandle,
"?*INSTR",
byref(instr_list),
byref(nb),
byref(desc)))
# The previous line prints: -1073807343
print(instr_list)
# The previous line prints: c_ulong(0)
Я пытался найти значение кода ошибки -1073807343 (4000FFEF в шестнадцатеричном формате) в Интернете, и хотя я нашел несколько веток по этому поводу на форумах National Instruments, я до сих пор не совсем понимаю, что это значит.
Буду признателен за любые советы, рекомендации или ссылки на соответствующую информацию.
1 ответ
Буквальный "?*INSTR"
создает str
объект, который является Unicode в Python 3. ctypes преобразует строку Unicode в wchar_t *
, В Windows wchar_t
2 байта, поэтому ctypes передает указатель на кодированный буфер UTF-16 "?\x00*\x00I\x00N\x00S\x00T\x00R\x00"
, Имейте в виду, что функция ожидает строку с нулевым символом в конце.
Чтобы вместо этого передать байтовую строку, перед литералом следует b
создать bytes
объект, то есть использование b"?*INSTR"
,
Чтобы ошибка, подобная этой, не прошла незамеченной, определите указатель функции argtypes
, ctypes поднимет ArgumentError
если юникод str
аргумент передается для параметра, который определен как 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)
Справочное руководство программиста NI-VISA на стр. 5-30 гласит, что instrDesc
должно быть не менее 256 байт.