Использование 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 байт.

Другие вопросы по тегам