$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 
48 #include <type_traits> // for is_base_of, conditional<>, false_type
49 
50 /*
51  * When creating a plugin, only the symbols that are loaded should be made
52  * visible. This can be achieved by setting compile options:
53  *
54  * -fvisibility=hidden -fvisibility-inlines-hidden
55  *
56  * This macro then makes select symbols that we want to export visible again.
57  */
58 #define DLL_PUBLIC __attribute__((visibility("default")))
59 
60 /*
61  * This definition is used for tracking changes to the plugin manifest.
62  */
63 #define CLOE_PLUGIN_MANIFEST_VERSION 1
64 
65 /*
66  * This can be set to a compatible setting as defined in the system header
67  * dlfcn.h. The default is equivalent to RTLD_LOCAL. Prefer defining this
68  * with the defines from the system header rather than on the command line.
69  *
70  * Note that if set to anything other than 0, one of RTLD_NOW and RTLD_LAZY
71  * must be specified in addition, as per the manual of dlopen().
72  *
73  * Example: RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY
74  */
75 #ifndef CLOE_PLUGIN_GLIBC_DLOPEN_MODE
76 #define CLOE_PLUGIN_GLIBC_DLOPEN_MODE 0
77 #endif
78 
79 /*
80  * This complex looking beast of code basically contains two switches on the
81  * base type of the factory xFactoryType. Ideally, we'd like to be able to
82  * just be able to do this:
83  *
84  * xFactoryType::PLUGIN_TYPE,
85  *
86  * But PLUGIN_TYPE and PLUGIN_API_VERSION are static members of the base
87  * factories, and are thus not available on the xFactoryType. So first we
88  * find out through is_base_of and conditional.
89  */
90 #define BASE_CLOE_FACTORY(xFactoryType) \
91  std::conditional<std::is_base_of<::cloe::ControllerFactory, xFactoryType>::value, \
92  ::cloe::ControllerFactory, \
93  typename std::conditional< \
94  std::is_base_of<::cloe::SimulatorFactory, xFactoryType>::value, \
95  ::cloe::SimulatorFactory, \
96  typename std::conditional< \
97  std::is_base_of<::cloe::ComponentFactory, xFactoryType>::value, \
98  ::cloe::ComponentFactory, std::false_type>::type>::type>::type
99 
124 #define EXPORT_CLOE_PLUGIN(xFactoryType) \
125  extern "C" DLL_PUBLIC const uint8_t cloe_plugin_manifest_version = CLOE_PLUGIN_MANIFEST_VERSION; \
126  extern "C" DLL_PUBLIC const ::cloe::PluginManifest cloe_plugin_manifest{ \
127  BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_TYPE, \
128  BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_API_VERSION, \
129  "cloe_plugin_create", \
130  CLOE_PLUGIN_GLIBC_DLOPEN_MODE, \
131  }; \
132  extern "C" DLL_PUBLIC ::cloe::ModelFactory* cloe_plugin_create() { return new xFactoryType{}; }
133 
134 namespace cloe {
135 
136 // Forward declarations:
137 class ControllerFactory;
138 class SimulatorFactory;
139 class ComponentFactory;
140 class ModelFactory;
141 
153  const char* plugin_type;
154 
158  const char* plugin_type_version;
159 
164  const char* factory_symbol;
165 
176 };
177 
178 } // namespace cloe
Definition: plugin.hpp:149
const char * factory_symbol
Definition: plugin.hpp:164
int glibc_dlopen_mode
Definition: plugin.hpp:175
const char * plugin_type
Definition: plugin.hpp:153
const char * plugin_type_version
Definition: plugin.hpp:158