LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

ActiveX to Call a LabVIEW VI from Visual C++

Has anyone been able to run the example "Using ActiveX to Call a LabVIEW VI from Visual C++" with Microsoft Visual studio 2010? Below is the code i am compiling. The code compiles and builds but the console hangs for about a minute or two then displays  ("LV must be running, exiting ...\n"). It seems if  the c++ application can not create an instance with the LV application.  Has anyone ran into this issue ?

 

// Acquire.cpp : This source code is an Automation client. It calls the
// LabVIEW 7.1's automation server.

#import "C:\Program Files\National Instruments\LabVIEW 2011\resource\labview.tlb"
#define VI_PATH "C:\\Documents and Settings\\trujilloaa\\My Documents\\Comm Example\\LabView Call\\var_test.vi"

#include "windows.h"   
#include "stdio.h"   
#include "conio.h"   
#include <stdlib.h>   
#include <string.h>   
 

// Include the LabVIEW Automation Server Type Libraries
//#import LABVIEW_TLB_PATH
 
 main()
{    // declare variant data structures
    // _variant_t is a class wrapper for variant data types
    _variant_t one_str;
    _variant_t str_list;
 
    int size = 0;
    char Path[1000],Password[60] = "";
 
    // a SAFEARRAY is used to access the data from an array
    SAFEARRAY *psa = NULL;
 
    char VIPath[100] = "C:\\Documents and Settings\\trujilloaa\\My Documents\\Comm Example\\LabView Call\\var_test.vi" ;
            
    // generate a  namespace declaration to and identify and assign a name to a declarative region.
    // In this case we are assigning the LabVIEW.
    using namespace LabVIEW;
    _ApplicationPtr pLV;
    VirtualInstrumentPtr pVI;
 
    CoInitialize(NULL);

    // Create Reference to LabVIEW ActiveX COM object
    pLV.CreateInstance("LabVIEW.Application");
    if (pLV == NULL)
    {    printf("LV must be running, exiting ...\n");
        return false;
        //break;
    }
    
    // Create Reference to VI
    pVI.CreateInstance("LabVIEW.VirtualInstrument");

    //strcpy(Path, pLV->ApplicationDirectory);
    strcpy(Path, VIPath);
                        
    // assign an object reference to the pVI.
    pVI = pLV->GetVIReference(LPCTSTR(Path), LPCTSTR(Password), 0,0x01);
 
    // configure the VI to show its front panel on Call.
    pVI->ShowFPOnCall = TRUE;
 
    // set the values for the controls of the VI
    pVI->SetControlValue("StrIn0", "String 1");
    pVI->SetControlValue("StrIn1", "String 2");
    pVI->SetControlValue("StrIn2", "String 3");
                        
    //Transfer control to LabVIEW with the Run statement.  The call function passes the parameter names
    // and data to the LabVIEW VI.
    pVI->Run(0);
 
    // Get the values from the indicators.  GetControlValue returns a _variant_t
    // type.  Here we explicitly assign our string values as _bstr_t.
    one_str = pVI->GetControlValue(_bstr_t("StrOut"));
    str_list = pVI->GetControlValue(_bstr_t("LstStrOut"));
            
    // We can use V_VT(&_variant_t) to test the type of our variant.  The variant
    // data structure stores several different type values and an attribute
    // for which type this variant should be converted to.
    if (V_VT(&one_str) == (VT_BSTR))
    {    printf("One String is a bstring\n");    }

    // assign our SAFEARRAY to the array type of the variant
    if (V_VT(&str_list) == ( VT_ARRAY | VT_BSTR ))
    {    printf("This is an array of bstrings\n");
        psa = V_ARRAY(&str_list);
    }
    
    HRESULT hr;
    LONG cElements, lLBound, lUBound;
    BSTR HUGEP *pbstr;
 
    // Get the number of dimensions of our array
    printf("Number of channels: %d\n",SafeArrayGetDim(psa));    
 
    // Get the lower bound
    hr = SafeArrayGetLBound(psa, 1, &lLBound);
    if (FAILED(hr)) return false;
 
    //Get upper bound
    hr = SafeArrayGetUBound(psa, 1, &lUBound);
    if (FAILED(hr)) return false;
 
    //Get total number of elements
    cElements = lUBound-lLBound+1;
 
    // Use SafeArrayAccessData to place a lock on the data so that we
    // can access the data in our application
    hr = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pbstr);
    if (FAILED(hr))return false;
 
    //  Iterate through the array and print the values
    for (int i = 0; i < cElements; i++)
    {    _bstr_t mybstr(pbstr[i]);
        printf("Data:<%s>\n",(char*)mybstr);                                
    }
 
    // Unlock the data
    SafeArrayUnaccessData(psa);

    // make sure the output is flushed to the screen
    fflush( stdin );
    
    while(!kbhit());
 
    return (0);
}

0 Kudos
Message 1 of 5
(3,897 Views)

Hi antz24,

 

Which version of LabVIEW are you using?  This example was developed and verified for Visual c++ 6.0 and LabVIEW 7.1.  If you are using a different version of LabVIEW, it is likely that the ActiveX methods have changed.  Below are the ActiveX methods for LabVIEW 2012:

 

http://zone.ni.com/reference/en-XX/help/371361J-01/axprop/vi_class_method/

 

Here is some documentation on calling LabVIEW VIs using different programming languages.

 

http://www.ni.com/white-paper/5719/en#toc1

 

Also, what exactly is it that you are trying to do?  In most cases, your application would probably be best served if it interfaced with your LabVIEW VI as a DLL.

Andrew T.
National Instruments
Message 2 of 5
(3,857 Views)

The version i am currently using  is LabVIEW 2011. We have used a DLL in the past but that will not work for this particular issue. We need to pass a FPGA board handle through our software in order to rd and wr registers. Currently we have a dll which simply opens and closes the board everytime we wanted to rd or wr. We found out the there is a memory leak in the board devlopers API and since we read and write mulitple times we need to just open and close the board once during the entire Labview session . Active X we felt was the best option . I am hoping i can pass data from Labview to C++ while having a application in the background that keeps the global handle open for reading and writing regs .The call to create a Application object should be CreateInstance("Labview.Application")  correct? The code i have currently does not even create an  application object. What occurs is it starts Labview and then errors out. I dont know if it is a coding issue or a permissions issue.    

0 Kudos
Message 3 of 5
(3,853 Views)

Hi antz24,

 

I believe you are correct in how you are creating your application object.  As of right now I am unsure on whether your error is resulting from your LabVIEW 2011 interfacing with what may be out-of-date ActiveX calls or not, I'm still looking into examples of using ActiveX as a server with LabVIEW 2011.  What type of C++ are you programming with?

Andrew T.
National Instruments
0 Kudos
Message 4 of 5
(3,832 Views)
Hello, I am thinking of using ActiveX to control a Labview 2011 VI using C++. I wanted to ask whether the issue posted in this thread has been resolved? Irham
0 Kudos
Message 5 of 5
(3,712 Views)