ISIS Logo
lvDCOM
An EPICS support module to export LabVIEW values as process variables
lvDCOMInterface.h
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2013 Science and Technology Facilities Council (STFC), GB.
3 * All rights reverved.
4 * This file is distributed subject to a Software License Agreement found
5 * in the file LICENSE.txt that is included with this distribution.
6 \*************************************************************************/
7 
10 
11 #ifndef LV_DCOM_INTERFACE_H
12 #define LV_DCOM_INTERFACE_H
13 
14 #include <stdio.h>
15 
16 //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
17 #include <windows.h>
18 #include <tchar.h>
19 //#include <sys/stat.h>
20 //#include <process.h>
21 //#include <fcntl.h>
22 
23 #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
24 #include <atlbase.h>
25 #include <atlstr.h>
26 #include <atlcom.h>
27 #include <atlwin.h>
28 #include <atltypes.h>
29 #include <atlctl.h>
30 #include <atlhost.h>
31 
32 #include <string>
33 #include <vector>
34 #include <map>
35 #include <list>
36 #include <stdexcept>
37 #include <sstream>
38 #include <fstream>
39 #include <iostream>
40 
41 #include <epicsMutex.h>
42 #include <epicsThread.h>
43 #include <epicsExit.h>
44 #include <macLib.h>
45 
46 //#import "LabVIEW.tlb" named_guids
47 // The above statement would generate labview.tlh and labview.tli from an installed copy of LabVIEW, but we include pre-built versions in the source
48 #include "labview.tlh"
49 
50 #include <msxml2.h>
51 
52 // TinyXPath, we tried this but it did not work, so use msxml as we will always be on Windows
53 //#include <xpath_processor.h>
54 //#include <xpath_static.h>
55 
57 struct ViRef
58 {
59  LabVIEW::VirtualInstrumentPtr vi_ref;
60  bool reentrant;
61  bool started;
62  ViRef(LabVIEW::VirtualInstrumentPtr vi_ref_, bool reentrant_, bool started_) : vi_ref(vi_ref_), reentrant(reentrant_), started(started_) { }
63  ViRef() : vi_ref(NULL), reentrant(false), started(false) { }
64 };
65 
69 {
74  lvNoStart = 16,
75  lvSECIConfig = 32,
77 };
78 
81 {
82 public:
83  lvDCOMInterface(const char* configSection, const char *configFile, const char* host, int options, const char* progid, const char* username, const char* password);
84  long nParams();
85  void getParams(std::map<std::string,std::string>& res);
86  template<typename T> void setLabviewValue(const char* param, const T& value);
87  template<typename T> void getLabviewValue(const char* param, T* value);
88  template<typename T> void getLabviewValue(const char* param, T* value, size_t nElements, size_t& nIn);
89  ~lvDCOMInterface() { if (m_pxmldom != NULL) { m_pxmldom->Release(); m_pxmldom = 0; } }
90  std::string doPath(const std::string& xpath);
91  std::string doXPATH(const std::string& xpath);
92  bool doXPATHbool(const std::string& xpath);
93  void report(FILE* fp, int details);
94  static double diffFileTimes(const FILETIME& f1, const FILETIME& f2);
95  int generateFilesFromSECI(const char* portName, const char* macros, const char* configSection, const char* configFile,
96  const char* dbSubFile, const char* blocks_match, bool no_setter);
98 
99 private:
100  std::string m_configSection;
101  std::string m_configFile;
102  std::string m_host;
103  std::string m_progid;
104  CLSID m_clsid;
105  std::string m_username;
106  std::string m_password;
107  static double m_minLVUptime;
108  int m_options;
109  typedef std::map<std::wstring, ViRef> vi_map_t;
111  epicsMutex m_lock;
112  // TiXmlDocument* m_doc;
113  // TiXmlElement* m_root;
114  IXMLDOMDocument2 *m_pxmldom;
115  CComBSTR m_extint;
116  CComPtr<LabVIEW::_Application> m_lv;
117  COAUTHIDENTITY* m_pidentity;
118  std::map<std::string,std::string> m_xpath_map;
119  std::map<std::string,bool> m_xpath_bool_map;
120  MAC_HANDLE *m_mac_env;
121  static std::vector< std::vector<std::string> > m_seci_values;
122 
123  void DomFromCOM();
124  char* envExpand(const char *str);
125  void getViRef(BSTR vi_name, bool reentrant, LabVIEW::VirtualInstrumentPtr &vi);
126  void createViRef(BSTR vi_name, bool reentrant, LabVIEW::VirtualInstrumentPtr &vi);
127  void getLabviewValue(BSTR vi_name, BSTR control_name, VARIANT* value);
128  void setLabviewValue(BSTR vi_name, BSTR control_name, const VARIANT& value);
129  void setLabviewValueExt(BSTR vi_name, BSTR control_name, const VARIANT& value, VARIANT* results);
130  void callLabview(BSTR vi_name, VARIANT& names, VARIANT& values, VARIANT_BOOL reentrant, VARIANT* results);
131  void waitForLabviewBoolean(BSTR vi_name, BSTR control_name, bool value);
132  COAUTHIDENTITY* createIdentity(const std::string& user, const std::string& domain, const std::string& pass);
133  HRESULT setIdentity(COAUTHIDENTITY* pidentity, IUnknown* pUnk);
134  static void epicsExitFunc(void* arg);
135  void stopVis(bool only_ones_we_started);
136  bool checkOption(lvDCOMOptions option) { return ( m_options & static_cast<int>(option) ) != 0; }
137  double getLabviewUptime();
138  std::string getLabviewValueType(BSTR vi_name, BSTR control_name);
139  double waitForLabVIEW();
141  void getBlockDetails(std::vector< std::vector<std::string> >& values);
142 };
143 
144 #endif /* LV_DCOM_INTERFACE_H */
lvDCOMOptions
Options that can be passed from EPICS iocsh via lvDCOMConfigure command.
COAUTHIDENTITY * m_pidentity
std::string m_configSection
section of configFile to load information from
(4) On IOC exit, stop any LabVIEW VIs that we started due to viStartIfIdle being specified ...
CComPtr< LabVIEW::_Application > m_lv
bool checkForNewBlockDetails()
std::string m_progid
bool started
did we start this vi because it was idle and viStartIfIdle was specified
void waitForLabviewBoolean(BSTR vi_name, BSTR control_name, bool value)
(8) On IOC exit, stop any LabVIEW VIs that we have connected to
MAC_HANDLE * m_mac_env
std::string doPath(const std::string &xpath)
std::string m_password
IXMLDOMDocument2 * m_pxmldom
void callLabview(BSTR vi_name, VARIANT &names, VARIANT &values, VARIANT_BOOL reentrant, VARIANT *results)
static std::vector< std::vector< std::string > > m_seci_values
horrible - do properly some time
void report(FILE *fp, int details)
Helper for EPICS driver report function.
(16) Do not start LabVIEW, connect to existing instance otherwise fail. As loading a Vi starts labvie...
bool reentrant
is the VI reentrant
double waitForLabVIEW()
wait for LabVIEW to have been running for m_minLVUptime seconds
int m_options
the various lvDCOMOptions currently in use
std::map< std::string, bool > m_xpath_bool_map
void getParams(std::map< std::string, std::string > &res)
(32) Automatically set if lvDCOMSECIConfigure() has been used
std::string doXPATH(const std::string &xpath)
std::map< std::string, std::string > m_xpath_map
void getBlockDetails(std::vector< std::vector< std::string > > &values)
double getLabviewUptime()
returns -1.0 if labview not running, else labview uptime in seconds
static void epicsExitFunc(void *arg)
void stopVis(bool only_ones_we_started)
int generateFilesFromSECI(const char *portName, const char *macros, const char *configSection, const char *configFile, const char *dbSubFile, const char *blocks_match, bool no_setter)
generate XML and DB files for SECI blocks
void maybeWaitForLabVIEWOrExit()
static double m_minLVUptime
minimum time labview must be running before connection made in &quot;lvNoStart&quot; mode
Manager class for LabVIEW DCOM Interaction. Parses an lvinput.xml file and provides access to the Lab...
void setLabviewValue(const char *param, const T &value)
std::map< std::wstring, ViRef > vi_map_t
ViRef(LabVIEW::VirtualInstrumentPtr vi_ref_, bool reentrant_, bool started_)
HRESULT setIdentity(COAUTHIDENTITY *pidentity, IUnknown *pUnk)
(1) If the LabVIEW VI is idle when we connect to it, issue a warning message
Hold a reference to a LabVIEW VI.
void getLabviewValue(const char *param, T *value)
std::string getLabviewValueType(BSTR vi_name, BSTR control_name)
determine best epics type for a labvier variable, this will be used to choose the appropriate EPICS r...
(2) If the LabVIEW VI is idle when we connect to it, attempt to start it
std::string m_configFile
static double diffFileTimes(const FILETIME &f1, const FILETIME &f2)
filetime uses 100ns units, returns difference in seconds
std::string m_host
(64) Do not generate setter XML / :SP PVs in SECI mode
COAUTHIDENTITY * createIdentity(const std::string &user, const std::string &domain, const std::string &pass)
bool checkOption(lvDCOMOptions option)
void createViRef(BSTR vi_name, bool reentrant, LabVIEW::VirtualInstrumentPtr &vi)
void setLabviewValueExt(BSTR vi_name, BSTR control_name, const VARIANT &value, VARIANT *results)
char * envExpand(const char *str)
expand epics environment strings using previously saved environment based on EPICS macEnvExpand() ...
std::string m_username
LabVIEW::VirtualInstrumentPtr vi_ref
bool doXPATHbool(const std::string &xpath)
lvDCOMInterface(const char *configSection, const char *configFile, const char *host, int options, const char *progid, const char *username, const char *password)
section name of configFile we will load settings from
void getViRef(BSTR vi_name, bool reentrant, LabVIEW::VirtualInstrumentPtr &vi)
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5