RobotTestingFramework  2.0.1
Robot Testing Framework
SharedLibraryClassApi.h
Go to the documentation of this file.
1 /*
2  * Robot Testing Framework
3  *
4  * Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 
22 #ifndef ROBOTTESTINGFRAMEWORK_SHAREDLIBRARYCLASSAPI_H
23 #define ROBOTTESTINGFRAMEWORK_SHAREDLIBRARYCLASSAPI_H
24 
26 #include <cstring>
27 
28 namespace shlibpp {
29 struct SharedLibraryClassApi;
30 }
31 
32 // Be careful loading C++ classes from DLLs. Generally you
33 // need an exact or very close match between compilers used
34 // to compile those DLLs and your own code.
35 
36 extern "C" {
37 
46 {
47 public:
48  int startCheck; // Constant: this should be 'S' 'H' 'P' 'P'.
49  // Don't touch anything further if it isn't.
50  int structureSize; // size of the SharedLibraryClassApi.
51  // If this doesn't match what you expect,
52  // Don't touch anything further if it isn't.
53  int systemVersion; // Overall version of plugin system.
54  // This does *not* cover compiler version etc.
55  void* (*create)(); // Instantiate a plugin object.
56  void (*destroy)(void* obj); // Destroy a plugin object.
57  int (*getVersion)(char* ver, int len); // Plugin-related version.
58  int (*getAbi)(char* abi, int len); // Compiler-related version.
59  int (*getClassName)(char* name, int len); // Name of plugin (subclass).
60  int (*getBaseClassName)(char* name, int len); // Name superclass.
62  int endCheck; // Constant: should be 'P' 'L' 'U' 'G'.
63 };
64 }
65 
66 #define SHLIBPP_SHARED_CLASS_FN extern "C" SHLIBPP_EXPORT
67 
84 #define SHLIBPP_DEFINE_SHARED_SUBCLASS(factoryname, classname, basename) \
85  SHLIBPP_SHARED_CLASS_FN void* factoryname##_create() \
86  { \
87  classname* cn = new classname; \
88  auto* bn = dynamic_cast<basename*>(cn); \
89  if (!bn) \
90  delete cn; \
91  return static_cast<void*>(bn); \
92  } \
93  SHLIBPP_SHARED_CLASS_FN void factoryname##_destroy(void* obj) \
94  { \
95  classname* cn = dynamic_cast<classname*>(static_cast<basename*>(obj)); \
96  if (cn) \
97  delete cn; \
98  } \
99  SHLIBPP_SHARED_CLASS_FN int factoryname##_getVersion(char* ver, int len) \
100  { \
101  return 0; \
102  } \
103  SHLIBPP_SHARED_CLASS_FN int factoryname##_getAbi(char* abi, int len) \
104  { \
105  return 0; \
106  } \
107  SHLIBPP_SHARED_CLASS_FN int factoryname##_getClassName(char* name, int len) \
108  { \
109  char cname[] = #classname; \
110  strncpy(name, cname, len); \
111  return strlen(cname) + 1; \
112  } \
113  SHLIBPP_SHARED_CLASS_FN int factoryname##_getBaseClassName(char* name, int len) \
114  { \
115  char cname[] = #basename; \
116  strncpy(name, cname, len); \
117  return strlen(cname) + 1; \
118  } \
119  SHLIBPP_SHARED_CLASS_FN int factoryname(void* api, int len) \
120  { \
121  struct shlibpp::SharedLibraryClassApi* sapi = (struct shlibpp::SharedLibraryClassApi*)api; \
122  if (len < (int)sizeof(shlibpp::SharedLibraryClassApi)) \
123  return -1; \
124  sapi->startCheck = shlibpp::VOCAB('S', 'H', 'P', 'P'); \
125  sapi->structureSize = sizeof(shlibpp::SharedLibraryClassApi); \
126  sapi->systemVersion = 5; \
127  sapi->create = factoryname##_create; \
128  sapi->destroy = factoryname##_destroy; \
129  sapi->getVersion = factoryname##_getVersion; \
130  sapi->getAbi = factoryname##_getAbi; \
131  sapi->getClassName = factoryname##_getClassName; \
132  sapi->getBaseClassName = factoryname##_getBaseClassName; \
133  for (int i = 0; i < SHLIBPP_SHAREDLIBRARYCLASSAPI_PADDING; i++) { \
134  sapi->roomToGrow[i] = 0; \
135  } \
136  sapi->endCheck = shlibpp::VOCAB('P', 'L', 'U', 'G'); \
137  return sapi->startCheck; \
138  }
139 // The double cast in the _create() and _destroy() functions are
140 // required to ensure that everything works when `basename` is not the
141 // first inherited class:
142 // _create() will return a valid `basename` or a null pointer if
143 // `classname` does not inherit from `basename`.
144 // _destroy() will ensure that we are calling `classname` destructor
145 // even if `basename` is not the first inherited class. If the
146 // dynamic_cast fails, it will not delete the object (that is probably
147 // leaked), but it is less dangerous than executing some other random
148 // function.
149 
150 #define SHLIBPP_DEFAULT_FACTORY_NAME "shlibpp_default_factory"
151 #define SHLIBPP_DEFINE_DEFAULT_SHARED_CLASS(classname) SHLIBPP_DEFINE_SHARED_SUBCLASS(shlibpp_default_factory, classname, classname)
152 #define SHLIBPP_DEFINE_SHARED_CLASS(factoryname, classname) SHLIBPP_DEFINE_SHARED_SUBCLASS(factoryname, classname, classname)
153 
154 #endif // ROBOTTESTINGFRAMEWORK_SHAREDLIBRARYCLASSAPI_H
Collection of hooks for creating/destroying a plugin.
int(* getVersion)(char *ver, int len)
#define SHLIBPP_SHAREDLIBRARYCLASSAPI_PADDING
int roomToGrow[SHLIBPP_SHAREDLIBRARYCLASSAPI_PADDING]
int(* getClassName)(char *name, int len)
int(* getAbi)(char *abi, int len)
int(* getBaseClassName)(char *name, int len)