05-21-2010 10:10 AM
Is there a way to make it fail if it doesn't find a VI-a already running? Any ideas on why it's opening a new VI instead of reusing the one in memory. Is there a setting somewhere that would explain why this happens on the test machine and not my development machine.
I'm currently trying to control a VI from c++ using the ActiveX server on the VI in LabVIEW 9, I'm building the application using MS VC++ express 2010. This VI(lets call it VI-a is invoke node to get and set data on another VI-b. For testing I have a copy of VI-b that is gutted so it loads into memory but doesn't run, it connects to hardware I don't have in my development setup.
#import "PATH\LaVIEW.tlb"
static LabVIEW::_ApplicationPtr pLVApp = (LabVIEW::_ApplicationPtr) NULL;
static LabVIEW::VirtualInstrumentPtr pVI = (LabVIEW::VirtualInstrumentPtr) NULL;
void init_VI()
{
//Multithreaded application
CoInitializeEx(NULL, COINIT_MULTITHREADED);
pLVApp.CreateInstance("LabVIEW.Application");
//Error checking not shown
return;
}
void connect_to_fp()
{
HRESULT hr = S_OK;
char password[60] = "";
VARIANT_BOOL reserveForCall = VARIANT_FALSE;
long options = 0x20;
//Multithreaded application
CoInitializeEx(NULL, COINIT_MULTITHREADED);
pVI.CreateInstance("LabVIEW.VirtualInstrument");
pVI = pLVApp->GetVIReference(vi_path, LPCTSTR(password), reserveForCall, options);
//Error checking not shown
hr = pVI->OpenFrontPanel(VARIANT_TRUE, LabVIEW::eVisible)
return;
}
I wasn't able to try commenting out the CreateInstance call on the test machine. However removing it has had no effect on my development machine.
Details of my setup:
On my development machine I can run VI-a before starting the c++ application and it will connect and use the VI-a that is already running in memory or I can let the c++ application bring up VI-a. When I was running a test recently when I would get the reference to VI-a it would open a new FP for VI-a (I'm assuming it started a new instance of VI-a) instead of using the one that was currently loaded and running, the VI-a also isn't running like it normally does. The VI-a gets it's values from VI-b once at init but it never updates them again. Also there is a switch on VI-a that controls a status indicator that doesn't update when the switch when it is toggled. There is another indicator on a separate tab that shows how long a loop took to execute that is changing, which is why I believe it is at least partially running.
My biggest issue is that I haven't been able to recreate this on my development machine. Anytime I have VI-a open and running my c++ application reuses that one instead of trying to open a new one. My connection code is pretty much strait out of the c++/ActiveX example from NI.
Thanks.
Solved! Go to Solution.
05-21-2010 06:36 PM
Figured out what the issue was. Apparently LV uses projects as a kinda of a namespace. The bigger issue is that if you have a project open and then open a VI outside the project it "soft" adds it to the open project. It puts it in the projects namespace but doesn't actually add it to the project. You can check this by looking at the item list in the project and look at the VI panels title in the window.
To test this open a VI that uses VI refs to interact with another VI that is in a project. Then open the target VI in a project. If when you try to run the first VI it will open it's own instance of the second VI. However if you open the target VI that is in a project first then open the non project VI, it will be "soft" added and be able to interact with the target VI in the project.
05-22-2010 02:41 PM
I haven't found an answer to erroring out instead of creating a new instance but I did find a way to deal with the project issue. If you create an instance, then open the project, then open the VI from the projects instance it will work. New init_VI:
void init_VI()
{
//Multithreaded application
CoInitializeEx(NULL, COINIT_MULTITHREADED);
pLVMainApp.CreateInstance("LabVIEW.Application");
pLVPrj = pLVMainApp->OpenProject(PATH_TO_PROJECT);
pLVApp = pLVPrj->GetApplication();
//Error checking not shown
return;
}