Skip to content

Handling functions that return non-zero gracefully #11

Open

Description

@sidneycadot

Hi Pierre,

I've been toying with PyDAQmx for a bit, thanks for this -- looks like a well-done wrapper.

One thing I bumped into was this:

In C, it is possible to use PyDAQmx.DAQmxGetSysDevNames() with a NULL char* argument to get the number of characters that need to be reserved for the characater buffer. This will return a positive value that does not indicate a warning.

However, PyDAQmx wraps the C functions inside the 'mafunction' wrapper that auto-throws an exception whenever a function returns non-zero. So it is impossible (or at least a bit cumbersome) to use this function in this way.

Is there an easy way around this?

The best I could think of now was to catch the exception and extract the "error", by hand, like this, which seems rather roundabout. In the process, I also need to silence stdout because mafunction() prints a WARNING message when warnings happen.

def GetSysDevNames():

    import sys, io

    # We know that PyDAQmx.DAQmxGetSysDevNames(None, 0)
    # will return a positive value; PyDAQmx intercepts
    # this, prints a warning, then throws a DAQError in response.
    #
    # To work around this, we need to
    #
    #   (1) silence the print()
    #   (2) catch the error

    old_stdout = sys.stdout
    sys.stdout = io.StringIO() # dummy fiel to catch print() output

    try:
        numBytesNeeded = PyDAQmx.DAQmxGetSysDevNames(None, 0)
    except PyDAQmx.DAQError as e:
        numBytesNeeded = e.error

    # Restore stdout
    sys.stdout = old_stdout

    # We now know how many bytes are needed.
    # Allocate the buffer

    stringBuffer = ctypes.create_string_buffer(numBytesNeeded)

    # Get the device names
    PyDAQmx.DAQmxGetSysDevNames(stringBuffer, numBytesNeeded)

    # Extract the device name string
    return ctypes.string_at(stringBuffer)

Is there a simpler/better way to do this? It could be useful to provide a way to call NIDAQmx functions without invoking the automatic translation of nonzero return values to DAQError exceptions.

Activity

  1. clade commented on Apr 9, 2014

    @clade
    Owner

    Hi,

    I didn't know this feature. It should be possible to change the way
    error are caught for this function. I post a solution on a new branch
    (DAQmxGetSysFunction). Can you test it ? (I havn't)

    Pierre

    Le 09/04/2014 09:03, Sidney Cadot a écrit :

    Hi Pierre,

    I've been toying with PyDAQmx for a bit, thanks for this -- looks like
    a well-done wrapper.

    One thing I bumped into was this:

    In C, it is possible to use PyDAQmx.DAQmxGetSysDevNames() with a NULL
    char* argument to get the number of characters that need to be
    reserved for the characater buffer. This will return a positive value
    that does not indicate a warning.

    However, PyDAQmx wraps the C functions inside the 'mafunction' wrapper
    that auto-throws an exception whenever a function returns non-zero. So
    it is impossible (or at least a bit cumbersome) to use this function
    in this way.

    Is there an easy way around this?

    The best I could think of now was to catch the exception and extract
    the "error", by hand, like this, which seems rather roundabout. In the
    process, I also need to silence stdout because mafunction() prints a
    WARNING message when warnings happen.

    |def GetSysDevNames():

     import sys, io
    
     # We know that PyDAQmx.DAQmxGetSysDevNames(None, 0)
     # will return a positive value; PyDAQmx intercepts
     # this, prints a warning, then throws a DAQError in respose.
     #
     # To work around this, we need to
     #
     #   (1) silence the print()
     #   (2) catch the error
    
     old_stdout = sys.stdout
     sys.stdout = io.StringIO() # dummy fiel to catch print() output
    
     try:
         numBytesNeeded = PyDAQmx.DAQmxGetSysDevNames(None, 0)
     except PyDAQmx.DAQError as e:
         numBytesNeeded = e.error
    
     # Restore stdout
     sys.stdout = old_stdout
    
     # We now know how many bytes are needed.
     # Allocate the buffer
    
     stringBuffer = ctypes.create_string_buffer(numBytesNeeded)
    
     # Get the device names
     PyDAQmx.DAQmxGetSysDevNames(stringBuffer, numBytesNeeded)
    
     # Extract the device name string
     return ctypes.string_at(stringBuffer)
    

    |
    |

    Is there a simpler/better way to do this? It could be useful to
    provide a way to call NIDAQmx functions without invoking the automatic
    translation of nonzero return values to DAQError exceptions.

    —
    Reply to this email directly or view it on GitHub
    #11.

  2. sidneycadot commented on Apr 10, 2014

    @sidneycadot
    Author

    I checked out that branch.

    What is the proper way of testing it -- should I just do a "python setup.py install" (does that work properly on Python 3.3) ? Or is it possible to test this locally inside that directory?

    Unfortunately, I do not fully understand the way Python handles modules.

  3. apteryks commented on Sep 22, 2015

    @apteryks

    This seems to be fixed as of PyDAQmx 1.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions