Using LabVIEW 7.1 and VC++ 6.0.
I'm having trouble reading data out of an array indicator via ActiveX. I have the VI compiled as an EXE, and I'm using C++ to read the value. I can read scalars just fine using the following code (with appropriate changes), and the array comes back with the proper type for an array of floats (VT_ARRAY | VT_R4), but the dimensions obtained from SafeArrayGetLBound and SafeArrayGetUBound are 0 and -1, respectively. SafeArrayGetDim returns 1. There are 50-ish elements in the array, and even direct access to them returns nonsense values. Is there some extra encoding going on between the LabVIEW array and the ActiveX SafeArray?
The app code (tabs have been eaten by the forum monster):
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "conio.h"
#include
#include
#include
#import "MyApp.tlb"
#define VIPATH "C:\\LabVIEW\\MyApp\\DIAG\\AI Diagnostics.vi"
using namespace MyApp;
int main(int argc, char* argv[])
{
VARIANT sample;
int size = 0;
char Path[1000],Password[60] = "";
// generate a namespace declaration to and identify and assign a name to a declarative region.
// In this case we are assigning the LabVIEW.
_ApplicationPtr pLV;
VirtualInstrumentPtr pVI;
cout << "Pre-CoInitialize" << endl;
CoInitialize(NULL);
do
{
VariantInit(&sample);
cout << "Initialized, creating MyApp.Application instance" << endl;
pLV.CreateInstance("MyApp.Application");
if (pLV == NULL)
{
printf("LV must be running, exiting ...\n");
break;
}
cout << "Obtained App instance, creating VI instance" << endl;
pVI.CreateInstance("MyApp.VirtualInstrument");
cout << "Got VI instance" << endl;
strcpy(Path, VIPATH);
// assign an object reference to the pVI.
VARIANT_BOOL resvForCall = TRUE;
long options = 0x0;
cout << "Getting Ref to Desired VI" << endl;
pVI = pLV->GetVIReference(LPCTSTR(Path), LPCTSTR(Password), resvForCall, options);
// configure the VI to show its front panel on Call.
pVI->ShowFPOnCall = TRUE;
sample.vt = VT_ARRAY | VT_R4;
// Multiple reads to ensure that we don't get the default 0...
sample = pVI->GetControlValue("Count Data");
sample = pVI->GetControlValue("Count Data");
// Check dimensions (comes back as 1)
long cdim;
cdim = SafeArrayGetDim(sample.parray);
cout << "cdim = " << cdim << endl;
// Check variant type, should be VT_ARRAY | VT_R4
cout << "VT: " << sample.vt << endl;
cout << "VT_ARRAY | VT_R4: " << (VT_ARRAY | VT_R4) << endl;
// Check bounds before iterating over array to print values
HRESULT he;
bool goahead = true;
long lbound;
long ubound;
he = SafeArrayGetLBound(sample.parray, 1, &lbound);
if (FAILED(he)) {
cout << "Failed getting lower bound." << endl;
cout << "Bad Index? " << (DISP_E_BADINDEX == he) << endl;
goahead = false;
}
he = SafeArrayGetUBound(sample.parray, 1, &ubound);
if (FAILED(he)) {
cout << "Failed getting upper bound." << endl;
cout << "Bad Index? " << (DISP_E_BADINDEX == he) << endl;
goahead = false;
}
cout << "Lower Bound: " << lbound << endl;
cout << "Upper Bound: " << ubound << endl;
// Print each element
if (goahead) {
for (long i = lbound; i < ubound; i++) {
VARIANT val;
VariantInit(&val);
val.vt = VT_R4;
SafeArrayGetElement(sample.parray, &i, &val);
printf("%d The sample Value is %g\n", i, val.fltVal);
VariantClear(&val);
}
}
// Wait to quit
while( !kbhit() ) {
cout << "Hit any key to continue\r";
fflush( stdin );
}
pLV->AutomaticClose=0;
VariantClear(&sample);
} while (0);
CoUninitialize();
return (0);
}