YARP
Yet Another Robot Platform
SharedLibraryClassApi.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #ifndef YARP_OS_SHAREDLIBRARYCLASSAPI_H
7 #define YARP_OS_SHAREDLIBRARYCLASSAPI_H
8 
9 #include <yarp/conf/system.h>
10 
11 #include <yarp/os/Vocab.h>
12 
13 #include <cstring>
14 
15 // Be careful loading C++ classes from DLLs. Generally you
16 // need an exact or very close match between compilers used
17 // to compile those DLLs and your own code.
18 
19 #define YARP_SHAREDLIBRARYCLASSAPI_PADDING (30 - 2 * (YARP_POINTER_SIZE / 4))
20 
21 namespace yarp {
22 namespace os {
23 
24 extern "C" {
25 
33 {
34 public:
35  NetInt32 startCheck; // Constant: this should be 'Y' 'A' 'R' 'P'.
36  // Don't touch anything further if it isn't.
37  NetInt32 structureSize; // size of the SharedLibraryClassApi.
38  // If this doesn't match what you expect,
39  // Don't touch anything further if it isn't.
40  NetInt32 systemVersion; // Overall version of plugin system.
41  // This does *not* cover compiler version etc.
42  void* (*create)(); // Instantiate a plugin object.
43  void (*destroy)(void* obj); // Destroy a plugin object.
44  int (*getVersion)(char* ver, int len); // Plugin-related version.
45  int (*getAbi)(char* abi, int len); // Compiler-related version.
46  int (*getClassName)(char* name, int len); // Name of plugin (subclass).
47  int (*getBaseClassName)(char* name, int len); // Name superclass.
49  NetInt32 endCheck; // Constant: should be 'P' 'L' 'U' 'G'.
50 };
52 
53 } // extern "C"
54 
55 } // namespace os
56 } // namespace yarp
57 
58 #define YARP_SHARED_CLASS_FN extern "C" YARP_EXPORT
59 
76 #define YARP_DEFINE_SHARED_SUBCLASS(factoryname, classname, basename) \
77  YARP_SHARED_CLASS_FN void* factoryname##_create() \
78  { \
79  classname* cn = new classname; \
80  basename* bn = dynamic_cast<basename*>(cn); \
81  if (!bn) \
82  delete cn; \
83  return static_cast<void*>(bn); \
84  } \
85  YARP_SHARED_CLASS_FN void factoryname##_destroy(void* obj) \
86  { \
87  classname* cn = dynamic_cast<classname*>(static_cast<basename*>(obj)); \
88  if (cn) \
89  delete cn; \
90  } \
91  YARP_SHARED_CLASS_FN int factoryname##_getVersion(char* ver, int len) \
92  { \
93  return 0; \
94  } \
95  YARP_SHARED_CLASS_FN int factoryname##_getAbi(char* abi, int len) \
96  { \
97  return 0; \
98  } \
99  YARP_SHARED_CLASS_FN int factoryname##_getClassName(char* name, int len) \
100  { \
101  char cname[] = #classname; \
102  strncpy(name, cname, len); \
103  return strlen(cname) + 1; \
104  } \
105  YARP_SHARED_CLASS_FN int factoryname##_getBaseClassName(char* name, int len) \
106  { \
107  char cname[] = #basename; \
108  strncpy(name, cname, len); \
109  return strlen(cname) + 1; \
110  } \
111  YARP_SHARED_CLASS_FN int factoryname(void* api, int len) \
112  { \
113  struct yarp::os::SharedLibraryClassApi* sapi = (struct yarp::os::SharedLibraryClassApi*)api; \
114  if (len < (int)sizeof(yarp::os::SharedLibraryClassApi)) \
115  return -1; \
116  sapi->startCheck = yarp::os::createVocab32('Y', 'A', 'R', 'P'); \
117  sapi->structureSize = sizeof(yarp::os::SharedLibraryClassApi); \
118  sapi->systemVersion = 5; \
119  sapi->create = factoryname##_create; \
120  sapi->destroy = factoryname##_destroy; \
121  sapi->getVersion = factoryname##_getVersion; \
122  sapi->getAbi = factoryname##_getAbi; \
123  sapi->getClassName = factoryname##_getClassName; \
124  sapi->getBaseClassName = factoryname##_getBaseClassName; \
125  for (int i = 0; i < YARP_SHAREDLIBRARYCLASSAPI_PADDING; i++) { \
126  sapi->roomToGrow[i] = 0; \
127  } \
128  sapi->endCheck = yarp::os::createVocab32('P', 'L', 'U', 'G'); \
129  return sapi->startCheck; \
130  }
131 // The double cast in the _create() and _destroy() functions are
132 // required to ensure that everything works when `basename` is not the
133 // first inherited class:
134 // _create() will return a valid `basename` or a null pointer if
135 // `classname` does not inherit from `basename`.
136 // _destroy() will ensure that we are calling `classname` destructor
137 // even if `basename` is not the first inherited class. If the
138 // dynamic_cast fails, it will not delete the object (that is probably
139 // leaked), but it is less dangerous than executing some other random
140 // function.
141 
142 #define YARP_DEFAULT_FACTORY_NAME "yarp_default_factory"
143 #define YARP_DEFINE_DEFAULT_SHARED_CLASS(classname) YARP_DEFINE_SHARED_SUBCLASS(yarp_default_factory, classname, classname)
144 #define YARP_DEFINE_SHARED_CLASS(factoryname, classname) YARP_DEFINE_SHARED_SUBCLASS(factoryname, classname, classname)
145 
146 #endif // YARP_OS_SHAREDLIBRARYCLASS_H
#define YARP_SHAREDLIBRARYCLASSAPI_PADDING
std::int32_t NetInt32
Definition of the NetInt32 type.
Definition: NetInt32.h:30
The main, catch-all namespace for YARP.
Definition: dirs.h:16
Collection of hooks for creating/destroying a plugin.
int(* getVersion)(char *ver, int len)
NetInt32 roomToGrow[(30 - 2 *(8/4))]
int(* getClassName)(char *name, int len)
int(* getAbi)(char *abi, int len)
int(* getBaseClassName)(char *name, int len)
#define YARP_END_PACK
Ends 1 byte packing for structs/classes.
Definition: system.h:191
#define YARP_BEGIN_PACK
Starts 1 byte packing for structs/classes.
Definition: system.h:190