Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling functions that return non-zero gracefully #11

Open
sidneycadot opened this issue Apr 9, 2014 · 3 comments
Open

Handling functions that return non-zero gracefully #11

sidneycadot opened this issue Apr 9, 2014 · 3 comments

Comments

@sidneycadot
Copy link

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.

@clade
Copy link
Owner

clade commented Apr 9, 2014

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.

@sidneycadot
Copy link
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.

@Apteryks
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants