$darkmode
plugin.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
46 #pragma once
47 #ifndef CLOE_PLUGIN_HPP_
48 #define CLOE_PLUGIN_HPP_
49 
50 #include <type_traits> // for is_base_of, conditional<>, false_type
51 
52 /*
53  * When creating a plugin, only the symbols that are loaded should be made
54  * visible. This can be achieved by setting compile options:
55  *
56  * -fvisibility=hidden -fvisibility-inlines-hidden
57  *
58  * This macro then makes select symbols that we want to export visible again.
59  */
60 #define DLL_PUBLIC __attribute__((visibility("default")))
61 
62 /*
63  * This definition is used for tracking changes to the plugin manifest.
64  */
65 #define CLOE_PLUGIN_MANIFEST_VERSION 1
66 
67 /*
68  * This can be set to a compatible setting as defined in the system header
69  * dlfcn.h. The default is equivalent to RTLD_LOCAL. Prefer defining this
70  * with the defines from the system header rather than on the command line.
71  *
72  * Note that if set to anything other than 0, one of RTLD_NOW and RTLD_LAZY
73  * must be specified in addition, as per the manual of dlopen().
74  *
75  * Example: RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY
76  */
77 #ifndef CLOE_PLUGIN_GLIBC_DLOPEN_MODE
78 #define CLOE_PLUGIN_GLIBC_DLOPEN_MODE 0
79 #endif
80 
81 /*
82  * This complex looking beast of code basically contains two switches on the
83  * base type of the factory xFactoryType. Ideally, we'd like to be able to
84  * just be able to do this:
85  *
86  * xFactoryType::PLUGIN_TYPE,
87  *
88  * But PLUGIN_TYPE and PLUGIN_API_VERSION are static members of the base
89  * factories, and are thus not available on the xFactoryType. So first we
90  * find out through is_base_of and conditional.
91  */
92 #define BASE_CLOE_FACTORY(xFactoryType) \
93  std::conditional<std::is_base_of<::cloe::ControllerFactory, xFactoryType>::value, \
94  ::cloe::ControllerFactory, \
95  typename std::conditional< \
96  std::is_base_of<::cloe::SimulatorFactory, xFactoryType>::value, \
97  ::cloe::SimulatorFactory, \
98  typename std::conditional< \
99  std::is_base_of<::cloe::ComponentFactory, xFactoryType>::value, \
100  ::cloe::ComponentFactory, std::false_type>::type>::type>::type
101 
126 #define EXPORT_CLOE_PLUGIN(xFactoryType) \
127  extern "C" DLL_PUBLIC const uint8_t cloe_plugin_manifest_version = CLOE_PLUGIN_MANIFEST_VERSION; \
128  extern "C" DLL_PUBLIC const ::cloe::PluginManifest cloe_plugin_manifest{ \
129  BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_TYPE, \
130  BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_API_VERSION, \
131  "cloe_plugin_create", \
132  CLOE_PLUGIN_GLIBC_DLOPEN_MODE, \
133  }; \
134  extern "C" DLL_PUBLIC ::cloe::ModelFactory* cloe_plugin_create() { return new xFactoryType{}; }
135 
136 namespace cloe {
137 
138 // Forward declarations:
139 class ControllerFactory;
140 class SimulatorFactory;
141 class ComponentFactory;
142 class ModelFactory;
143 
155  const char* plugin_type;
156 
160  const char* plugin_type_version;
161 
166  const char* factory_symbol;
167 
178 };
179 
180 } // namespace cloe
181 
182 #endif // CLOE_PLUGIN_HPP_
const char * factory_symbol
Definition: plugin.hpp:166
int glibc_dlopen_mode
Definition: plugin.hpp:177
const char * plugin_type
Definition: plugin.hpp:155
Definition: coordinator.hpp:36
Definition: plugin.hpp:151
const char * plugin_type_version
Definition: plugin.hpp:160