system.cc
Go to the documentation of this file.
1 /*
2  * This file is part of the rc_genicam_api package.
3  *
4  * Copyright (c) 2017 Roboception GmbH
5  * All rights reserved
6  *
7  * Author: Heiko Hirschmueller
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "system.h"
37 
38 #include "gentl_wrapper.h"
39 #include "exception.h"
40 #include "interface.h"
41 #include "cport.h"
42 
43 #include <iostream>
44 
45 #ifdef _WIN32
46 #include <Windows.h>
47 #include <cstring>
48 #undef min
49 #undef max
50 #endif
51 
52 namespace rcg
53 {
54 
56 {
57  if (n_open > 0 && tl != 0)
58  {
59  gentl->TLClose(tl);
60  }
61 
62  gentl->GCCloseLib();
63 }
64 
65 namespace
66 {
67 
68 std::mutex system_mtx;
69 std::vector<std::shared_ptr<System> > slist;
70 
71 int find(const std::vector<std::shared_ptr<System> > &list, const std::string &filename)
72 {
73  for (size_t i=0; i<list.size(); i++)
74  {
75  if (list[i]->getFilename() == filename)
76  {
77  return static_cast<int>(i);
78  }
79  }
80 
81  return -1;
82 }
83 
84 #ifdef _WIN32
85 static std::string getPathToThisDll()
86 {
87  HMODULE hm = nullptr;
88  if (GetModuleHandleEx(
89  GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
90  GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
91  reinterpret_cast<LPCSTR>(&getPathToThisDll), &hm) == 0)
92  {
93  return {};
94  }
95 
96  char path[MAX_PATH];
97  if (GetModuleFileName(hm, path, sizeof(path)) == 0)
98  {
99  return {};
100  }
101 
102  std::string p{ path };
103  const auto bs_pos = p.rfind('\\');
104  if (bs_pos != std::string::npos)
105  {
106  p = p.substr(0, bs_pos);
107  }
108 
109  return p;
110 }
111 
112 #endif
113 
114 }
115 
116 std::vector<std::shared_ptr<System> > System::getSystems()
117 {
118  std::lock_guard<std::mutex> lock(system_mtx);
119  std::vector<std::shared_ptr<System> > ret;
120 
121  // get list of all available transport layer libraries
122 
123  const char *env=0;
124  if (sizeof(size_t) == 8)
125  {
126  env="GENICAM_GENTL64_PATH";
127  }
128  else
129  {
130  env="GENICAM_GENTL32_PATH";
131  }
132 
133  std::string path;
134 
135  const char *envpath=std::getenv(env);
136  if (envpath != 0)
137  {
138  path=envpath;
139  }
140 
141  if (path.size() == 0)
142  {
143 #ifdef _WIN32
144  // under Windows, use the path to the current executable as fallback
145 
146  const size_t n=256;
147  char procpath[n];
148  std::string path_to_exe;
149  if (GetModuleFileName(NULL, procpath, n-1) > 0)
150  {
151  procpath[n-1]='\0';
152 
153  char *p=strrchr(procpath, '\\');
154  if (p != 0) *p='\0';
155 
156  path_to_exe=procpath;
157  path+=";" + path_to_exe;
158  }
159 
160  const auto path_to_this_dll = getPathToThisDll();
161  if (!path_to_this_dll.empty() && path_to_this_dll != path_to_exe)
162  {
163  path += ";" + path_to_this_dll;
164  }
165 #else
166  // otherwise, use the absolute install path to the default transport layer
167 
168  path=GENTL_INSTALL_PATH;
169 #endif
170  }
171 
172  std::vector<std::string> name=getAvailableGenTLs(path.c_str());
173 
174  // create list of systems according to the list, using either existing
175  // systems or instantiating new ones
176 
177  for (size_t i=0; i<name.size(); i++)
178  {
179  int k=find(slist, name[i]);
180 
181  if (k >= 0)
182  {
183  ret.push_back(slist[static_cast<size_t>(k)]);
184  }
185  else
186  {
187  try
188  {
189  System *p=new System(name[i]);
190  ret.push_back(std::shared_ptr<System>(p));
191  }
192  catch (const std::exception &)
193  {
194  // ignore transport layers that cannot be used
195  }
196  }
197  }
198 
199  // remember returned list for reusing existing systems on the next call
200 
201  slist=ret;
202 
203  // throw exception if no transport layers are available
204 
205  if (ret.size() == 0)
206  {
207  throw GenTLException(std::string("No transport layers found in path ")+path);
208  }
209 
210  return ret;
211 }
212 
214 {
215  std::lock_guard<std::mutex> lock(system_mtx);
216  slist.clear();
217 }
218 
219 const std::string &System::getFilename() const
220 {
221  return filename;
222 }
223 
225 {
226  std::lock_guard<std::mutex> lock(mtx);
227 
228  if (n_open == 0)
229  {
230  if (gentl->TLOpen(&tl) != GenTL::GC_ERR_SUCCESS)
231  {
232  throw GenTLException("System::open()", gentl);
233  }
234  }
235 
236  n_open++;
237 }
238 
240 {
241  std::lock_guard<std::mutex> lock(mtx);
242 
243  if (n_open > 0)
244  {
245  n_open--;
246  }
247 
248  if (n_open == 0)
249  {
250  gentl->TLClose(tl);
251  tl=0;
252 
253  nodemap=0;
254  cport=0;
255  }
256 }
257 
258 namespace
259 {
260 
261 int find(const std::vector<std::shared_ptr<Interface> > &list, const std::string &id)
262 {
263  for (size_t i=0; i<list.size(); i++)
264  {
265  if (list[i]->getID() == id)
266  {
267  return static_cast<int>(i);
268  }
269  }
270 
271  return -1;
272 }
273 
274 }
275 
276 std::vector<std::shared_ptr<Interface> > System::getInterfaces()
277 {
278  std::lock_guard<std::mutex> lock(mtx);
279  std::vector<std::shared_ptr<Interface> > ret;
280 
281  if (tl != 0)
282  {
283  // get list of previously requested interfaces that are still in use
284 
285  std::vector<std::shared_ptr<Interface> > current;
286 
287  for (size_t i=0; i<ilist.size(); i++)
288  {
289  std::shared_ptr<Interface> p=ilist[i].lock();
290  if (p)
291  {
292  current.push_back(p);
293  }
294  }
295 
296  // update available interfaces
297 
298  if (gentl->TLUpdateInterfaceList(tl, 0, 10) != GenTL::GC_ERR_SUCCESS)
299  {
300  throw GenTLException("System::getInterfaces()", gentl);
301  }
302 
303  // create list of interfaces, using either existing interfaces or
304  // instantiating new ones
305 
306  uint32_t n=0;
307  if (gentl->TLGetNumInterfaces(tl, &n) != GenTL::GC_ERR_SUCCESS)
308  {
309  throw GenTLException("System::getInterfaces()", gentl);
310  }
311 
312  for (uint32_t i=0; i<n; i++)
313  {
314  char tmp[256]="";
315  size_t size=sizeof(tmp);
316 
317  if (gentl->TLGetInterfaceID(tl, i, tmp, &size) != GenTL::GC_ERR_SUCCESS)
318  {
319  throw GenTLException("System::getInterfaces()", gentl);
320  }
321 
322  int k=find(current, tmp);
323 
324  if (k >= 0)
325  {
326  ret.push_back(current[static_cast<size_t>(k)]);
327  }
328  else
329  {
330  ret.push_back(std::shared_ptr<Interface>(new Interface(shared_from_this(), gentl, tmp)));
331  }
332  }
333 
334  // update internal list of interfaces for reusage on next call
335 
336  ilist.clear();
337  for (size_t i=0; i<ret.size(); i++)
338  {
339  ilist.push_back(ret[i]);
340  }
341  }
342 
343  return ret;
344 }
345 
346 namespace
347 {
348 
349 std::string cTLGetInfo(GenTL::TL_HANDLE tl, const std::shared_ptr<const GenTLWrapper> &gentl,
350  GenTL::TL_INFO_CMD info)
351 {
352  std::string ret;
353 
355  char tmp[1024]="";
356  size_t tmp_size=sizeof(tmp);
358 
359  if (tl != 0)
360  {
361  err=gentl->TLGetInfo(tl, info, &type, tmp, &tmp_size);
362  }
363  else
364  {
365  err=gentl->GCGetInfo(info, &type, tmp, &tmp_size);
366  }
367 
369  {
370  for (size_t i=0; i<tmp_size && tmp[i] != '\0'; i++)
371  {
372  ret.push_back(tmp[i]);
373  }
374  }
375 
376  return ret;
377 }
378 
379 }
380 
381 std::string System::getID()
382 {
383  std::lock_guard<std::mutex> lock(mtx);
384  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_ID);
385 }
386 
387 std::string System::getVendor()
388 {
389  std::lock_guard<std::mutex> lock(mtx);
390  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_VENDOR);
391 }
392 
393 std::string System::getModel()
394 {
395  std::lock_guard<std::mutex> lock(mtx);
396  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_MODEL);
397 }
398 
399 std::string System::getVersion()
400 {
401  std::lock_guard<std::mutex> lock(mtx);
402  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_VERSION);
403 }
404 
405 std::string System::getTLType()
406 {
407  std::lock_guard<std::mutex> lock(mtx);
408  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_TLTYPE);
409 }
410 
411 std::string System::getName()
412 {
413  std::lock_guard<std::mutex> lock(mtx);
414  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_NAME);
415 }
416 
417 std::string System::getPathname()
418 {
419  std::lock_guard<std::mutex> lock(mtx);
420  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_PATHNAME);
421 }
422 
424 {
425  std::lock_guard<std::mutex> lock(mtx);
426  return cTLGetInfo(tl, gentl, GenTL::TL_INFO_DISPLAYNAME);
427 }
428 
430 {
431  std::lock_guard<std::mutex> lock(mtx);
432  bool ret=true;
433 
435  int32_t v;
436  size_t size=sizeof(v);
438 
439  if (tl != 0)
440  {
441  err=gentl->TLGetInfo(tl, GenTL::TL_INFO_CHAR_ENCODING, &type, &v, &size);
442  }
443  else
444  {
445  err=gentl->GCGetInfo(GenTL::TL_INFO_CHAR_ENCODING, &type, &v, &size);
446  }
447 
448  if (err == GenTL::GC_ERR_SUCCESS && type == GenTL::INFO_DATATYPE_INT32 &&
450  {
451  ret=false;
452  }
453 
454  return ret;
455 }
456 
458 {
459  std::lock_guard<std::mutex> lock(mtx);
460  uint32_t ret=0;
461 
463  size_t size=sizeof(ret);
464 
465  if (tl != 0)
466  {
467  gentl->TLGetInfo(tl, GenTL::TL_INFO_GENTL_VER_MAJOR, &type, &ret, &size);
468  }
469  else
470  {
471  gentl->GCGetInfo(GenTL::TL_INFO_GENTL_VER_MAJOR, &type, &ret, &size);
472  }
473 
474  return static_cast<int>(ret);
475 }
476 
478 {
479  std::lock_guard<std::mutex> lock(mtx);
480  uint32_t ret=0;
481 
483  size_t size=sizeof(ret);
484 
485  if (tl != 0)
486  {
487  gentl->TLGetInfo(tl, GenTL::TL_INFO_GENTL_VER_MINOR, &type, &ret, &size);
488  }
489  else
490  {
491  gentl->GCGetInfo(GenTL::TL_INFO_GENTL_VER_MINOR, &type, &ret, &size);
492  }
493 
494  return static_cast<int>(ret);
495 }
496 
497 std::shared_ptr<GenApi::CNodeMapRef> System::getNodeMap()
498 {
499  std::lock_guard<std::mutex> lock(mtx);
500  if (tl != 0 && !nodemap)
501  {
502  cport=std::shared_ptr<CPort>(new CPort(gentl, &tl));
503  nodemap=allocNodeMap(gentl, tl, cport.get());
504  }
505 
506  return nodemap;
507 }
508 
509 void *System::getHandle() const
510 {
511  return tl;
512 }
513 
514 System::System(const std::string &_filename)
515 {
516  filename=_filename;
517 
518  gentl=std::shared_ptr<const GenTLWrapper>(new GenTLWrapper(filename));
519 
520  if (gentl->GCInitLib() != GenTL::GC_ERR_SUCCESS)
521  {
522  throw GenTLException("System::System()", gentl);
523  }
524 
525  n_open=0;
526  tl=0;
527 }
528 
529 }
System(const std::string &_filename)
Definition: system.cc:514
std::string getDisplayName()
Returns the display name of the GenTL provider.
Definition: system.cc:423
std::shared_ptr< GenApi::CNodeMapRef > nodemap
Definition: system.h:241
const std::string & getFilename() const
Get file name from which this system was created.
Definition: system.cc:219
This is the port definition that connects GenAPI to GenTL.
Definition: cport.h:52
void * tl
Definition: system.h:238
int32_t TL_INFO_CMD
Definition: GenTL_v1_5.h:284
static std::vector< std::shared_ptr< System > > getSystems()
Returns a list of systems (i.e.
Definition: system.cc:116
void * getHandle() const
Get internal handle of open transport layer.
Definition: system.cc:509
std::shared_ptr< CPort > cport
Definition: system.h:240
std::vector< std::shared_ptr< Interface > > getInterfaces()
Returns the currently available interfaces.
Definition: system.cc:276
void close()
Closes the system.
Definition: system.cc:239
The system class encapsulates a Genicam transport layer.
Definition: system.h:58
std::mutex mtx
Definition: system.h:235
std::shared_ptr< const GenTLWrapper > gentl
Definition: system.h:233
int32_t GC_ERROR
Definition: GenTL_v1_5.h:181
static void clearSystems()
Clears the internal list of systems.
Definition: system.cc:213
int n_open
Definition: system.h:237
std::string getVendor()
Returns the vendor name of the GenTL provider.
Definition: system.cc:387
void * TL_HANDLE
Definition: GenTL_v1_5.h:218
int getMinorVersion()
Returns the minor version number.
Definition: system.cc:477
void open()
Opens the system for working with it.
Definition: system.cc:224
std::shared_ptr< GenApi::CNodeMapRef > getNodeMap()
Returns the node map of this object.
Definition: system.cc:497
std::string getName()
Returns the file name of the GenTL provider.
Definition: system.cc:411
std::vector< std::string > getAvailableGenTLs(const char *paths)
The function uses the given list files of paths that is separated by colons or semicolons, depending on the used operating system, and returns all files with the suffix .cti.
Wrapper for dynamically loaded GenICam transport layers.
Definition: gentl_wrapper.h:62
std::shared_ptr< GenApi::CNodeMapRef > allocNodeMap(std::shared_ptr< const GenTLWrapper > gentl, void *port, CPort *cport, const char *xml)
Convenience function that returns a GenICam node map from the given port.
Definition: cport.cc:133
bool isCharEncodingASCII()
Returns the character encoding.
Definition: system.cc:429
Definition: buffer.cc:42
std::string getVersion()
Returns the version of the GenTL provider.
Definition: system.cc:399
std::string getModel()
Returns the model of the GenTL provider.
Definition: system.cc:393
std::vector< std::weak_ptr< Interface > > ilist
Definition: system.h:243
std::string getPathname()
Returns the full path name of the GenTL provider.
Definition: system.cc:417
std::string filename
Definition: system.h:232
std::string getTLType()
Returns the transport layer type of the GenTL provider.
Definition: system.cc:405
int32_t INFO_DATATYPE
Definition: GenTL_v1_5.h:258
int getMajorVersion()
Returns the major version number.
Definition: system.cc:457
The interface class encapsulates a Genicam interface.
Definition: interface.h:54
std::string getID()
Returns the ID of the GenTL provider.
Definition: system.cc:381


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Thu Jun 6 2019 19:10:54