Вопрос

I'm working in Python and have installed the lastest version of NI-VISA. I'm using the ctypes package in order to load the visa32.dll installed with NI-VISA.

I used both the NI-VISA documentation, as well as the following page as a base for my code.

I already know of the pyVisa wrapper and using their find_resources function does return the instruments connected. However, I do not wish to use this wrapper and would rather use the VISA DLL file directly.

I've also been browsing the pyVisa code to see how they do it, and tried to learn from it, but it seems I still don't get it.

Here is my current unfinished code:

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)

I've been trying to find the meaning of the error code -1073807343 (4000FFEF in hex) on the Internet and though I have found some forum threads about it on the National Instruments forums, I still don't quite understand what it means.

I would welcome any advice, guidance or link towards relevant information.

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top