NI VISA C Function viParseRsrc() or viParseRsrcEx() Does Not Recognize Valid VISA Resource String

Updated May 12, 2023

Issue

I'm writing a C or C++ program for NI-VISA. In my program, I want to use either viParseRsrc() or viParseRsrcEx(), but both functions seem not to work or they return a status < 0.

Solution

First, make sure if your VISA resource string is correct. You can do so by several ways, but you might want to try one of these: If one of those two steps are correct, then you will have the correct resource string. In this case, check if parameters need to be set differently.

Check the other parameters of viParseRsrc() or viParseRsrcEx(). Make sure that both ViPUInt16 intfType and ViPUInt16 intfNum are passed by reference (using the & operator), and not by value.

The calls to the functions should be:
viParseRsrc(defaultRM, cInstrString, &intfType, &intfNum)
viParseRsrcEx(defaultRM, cInstrString, &intfType, &intfNum, &rsrcClass, &expandedUnaliasedName, &aliasIfExists)


When using viParseRsrcEx, you also need to provide the proper size for the ViChar buffers. These will work:

ViChar rsrcClass[20] = "0";
ViChar expandedUnaliasedName[20] = "0";
ViChar aliasIfExists[20] = "0";

 

Example Code

The following example code was created in Microsoft Visual Studio 2022. On a Windows system with NI-VISA installed, it uses a GPIB-USB-HB+ and a NI Instrument Simulator. With only slight adaptions, it will work both on Linux and for other VISA resources.
 
/********************************************************************/
/*             Simple Parse Resource Example                        */
/*                                                                  */
/* This example demonstrates how you might test your system for     */
/* the existence of a particular instrument.                        */
/*                                                                  */
/* The general flow of the code is                                  */
/*      Open Resource Manager                                       */
/*      Use viParseRsrcEx() to test for the existence of a specific */
/*          instrument                                              */
/*      Use viParseRsrc() to test for the existence of a specific   */
/*          instrument                                              */
/*      Open a session to this device                               */
/*      Close the VISA Session                                      */
/*                                                                  */
/* This example works well with a NI Instrument Simulator on        */
/* GPIB0::1::INSTR                                                  */
/********************************************************************/

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
/* Functions like strcpy are technically not secure because they do */
/* not contain a 'length'. But we disable this warning for the VISA */
/* examples since we never copy more than the actual buffer size.   */
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "visa.h"

static ViSession defaultRM;
static ViSession instr;
static ViStatus status;
static ViUInt32 retCount;
static ViUInt32 writeCount;
static char stringinput[512];

/*
* In every source code or header file that you use it is necessary to prototype
* your VISA variables at the beginning of the file. You need to declare the VISA
* session, VISA integers, VISA strings, VISA pointers, and VISA floating variables.
* Remember that if you are prototyping variables that are to be used as part of the
* VISA session that need this prototyping. As an example, above retCount has been
* prototyped as a static variable to this particular module.   It is an integer of
* bit length 32. If you are uncertain how to declare your VISA prototypes refer
* to the VISA help under the Section titled Type Assignments Table. The VISA
* help is located in your NI-VISA directory or folder.
*/

int main(void)
{
    /*
     * First we must call viOpenDefaultRM to get the resource manager
     * handle.  We will store this handle in defaultRM.
     */
    status = viOpenDefaultRM(&defaultRM);
    if (status < VI_SUCCESS)
    {
        printf("viOpenDefaultRM: Could not open a session to the VISA Resource Manager!\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("viOpenDefaultRM: Opened Session to the VISA Resource Manager.\n");
    }

    /*
     * Now we will open a VISA session to a device at Primary Address 1.
     * You can use any address for your instrument. In this example we are
     * using GPIB Primary Address 1.
     *
     * We must use the handle from viOpenDefaultRM and we must
     * also use a string that indicates which instrument to open.  This
     * is called the instrument descriptor.  The format for this string
     * can be found in the NI-VISA User Manual.
     * After opening a session to the device, we will get a handle to
     * the instrument which we will use in later VISA functions.
     * The two parameters in this function which are left blank are
     * reserved for future functionality.  These two parameters are
     * given the value VI_NULL.
     *
     * This example will also work for serial or VXI instruments by changing
     * the instrument descriptor from GPIB0::2::INSTR to ASRL1::INSTR or
     * VXI0::2::INSTR depending on the necessary descriptor for your
     * instrument.
     */

    ViRsrc cInstrString = "GPIB0::1::INSTR";
    char cStatusChar[100] = "none";

    ViPUInt16 intfType = 0; /* Interface type of the given resource string. */
    ViPUInt16 intfNum = 0; /* Board number of the interface of the given resource string. */
    ViChar rsrcClass[20] = "0";
    ViChar expandedUnaliasedName[20] = "0";
    ViChar aliasIfExists[20] = "0";

    status = viParseRsrcEx(defaultRM, cInstrString, &intfType, &intfNum, rsrcClass, expandedUnaliasedName, aliasIfExists);
    if (status < VI_SUCCESS)
    {
        printf("viParseRsrcEx of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource not ready / existing.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
    }
    else
    {
        printf("viParseRsrcEx of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource ready.\n");
    }

    status = viParseRsrc(defaultRM, cInstrString, &intfType, &intfNum);
    if (status < VI_SUCCESS)
    {
        printf("viParseRsrc of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource not ready / existing.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
    }
    else
    {
        printf("viParseRsrc of cInstrString[100] = \"GPIB0::1::INSTR\" before viOpen: Ressource ready.\n");
    }
    
    status = viOpen(defaultRM, cInstrString, VI_NULL, VI_NULL, &instr);
    if (status < VI_SUCCESS)
    {
        printf("viOpen of cInstrString[100] = \"GPIB0::1::INSTR\": Cannot open a session to the device.\n");
        printf("--Error Code: %d \n", status);
        viStatusDesc(&defaultRM, status, cStatusChar);
        printf("--Error Code: %s \n", cStatusChar);
        goto Close;
    }
    else
    {
        printf("viOpen of cInstrString[100] = \"GPIB0::1::INSTR\": Opened session to the device.\n");
    }

    /*
     * Now we will close the session to the instrument using
     * viClose. This operation frees all system resources.
     */
Close:
    printf("Closing Sessions\nHit enter to continue.");
    fflush(stdin);
    getchar();
    status = viClose(instr);
    status = viClose(defaultRM);

    return 0;
}