Simbody 3.7
Plugin.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_PLUGIN_H_
2#define SimTK_SimTKCOMMON_PLUGIN_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2009-12 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
34#include <string>
35#include <stdexcept>
36
37namespace SimTK {
38
97public:
98 explicit Plugin(const std::string& defaultPathname="");
99 ~Plugin(); // unloads the plugin if it was loaded
100
114 bool load(const std::string& name="");
115
120 void unload();
121
124 bool isLoaded() const {return m_handle != 0;}
125
126 const std::string& getLoadedPathname() const {
127 return m_loadedPathname; // empty if nothing loaded
128 }
129
132 std::string getLastErrorMessage() const {return m_lastMessage;}
133
139 void setSearchPath(const Array_<std::string>& pathIn) {
140 m_searchPath.clear();
141 for (unsigned i=0; i < pathIn.size(); ++i)
142 addSearchDirectory(pathIn[i]);
143 }
144
145 const Array_<std::string>& getSearchPath() const {return m_searchPath;}
146
150 void addSearchDirectory(const std::string& directory) {
151 const std::string absDir = Pathname::getAbsoluteDirectoryPathname(directory);
152 if (!absDir.empty())
153 m_searchPath.push_back(absDir);
154 }
155
160 void prependSearchDirectory(const std::string& directory) {
161 const std::string absDir = Pathname::getAbsoluteDirectoryPathname(directory);
162 if (!absDir.empty())
163 m_searchPath.insert(m_searchPath.begin(), absDir);
164 }
165
166
169 static void* loadPluginByFileName(const std::string& name, std::string& errMsg);
174 static void* loadDebugOrReleasePlugin(const std::string& base, const std::string& extension,
175 std::string& loadedFileName, std::string& errMsg);
178 static void* getSymbolAddress(void* handle, const std::string& name, std::string& errMsg);
181 static void unloadPlugin(void* handle);
182
224 static bool deconstructLibraryName( const std::string& name,
225 bool& isAbsolutePath,
226 std::string& directory,
227 std::string& libPrefix,
228 std::string& baseName,
229 std::string& debugSuffix,
230 std::string& extension);
231
235 static std::string getDynamicLibPrefix();
236
240 static std::string getDynamicLibExtension();
241
246 static std::string getDynamicLibDebugSuffix();
247
248protected:
249 std::string m_defaultName; // if any
251
252 std::string m_loadedPathname; // absolute
253 void* m_handle;
254 mutable std::string m_lastMessage;
255
256};
257
258
259#define SimTK_PLUGIN_XXX_MAKE_HOLDER(FuncName) \
260 struct FuncName##__Holder__ { \
261 FuncName##__Holder__() : fp(0) {} \
262 bool loadSym(void* h, std::string& msg) const { \
263 if(!fp) fp =(FuncName##__Type__) \
264 Plugin::getSymbolAddress(h, #FuncName, msg); \
265 return (fp!=0); \
266 } \
267 mutable FuncName##__Type__ fp; \
268 } FuncName##__Ref__
269#define SimTK_PLUGIN_XXX_MAKE_BODY(FuncName) \
270 if (!FuncName##__Ref__.loadSym(m_handle,m_lastMessage)) \
271 throw std::runtime_error \
272 ("Plugin function " #FuncName " not found: " + m_lastMessage); \
273 return FuncName##__Ref__.fp
274#define SimTK_PLUGIN_XXX_MAKE_SYMTEST(Symbol) \
275 bool has_##Symbol() const { \
276 return Symbol##__Ref__.loadSym(m_handle,m_lastMessage); \
277 }
278
279#define SimTK_PLUGIN_DEFINE_SYMBOL(Type, SymName) \
280 typedef Type SymName##__Type__; \
281 SimTK_PLUGIN_XXX_MAKE_HOLDER(SymName); \
282 const Type& SymName() const { \
283 if (!SymName##__Ref__.loadSym(m_handle,m_lastMessage)) \
284 throw std::runtime_error \
285 ("Plugin symbol " #SymName " not found: " + m_lastMessage); \
286 return *(SymName##__Ref__.fp); \
287 }
288
289#define SimTK_PLUGIN_DEFINE_FUNCTION(RetType, FuncName) \
290 typedef RetType (*FuncName##__Type__)(); \
291 SimTK_PLUGIN_XXX_MAKE_HOLDER(FuncName); \
292 RetType FuncName() const { \
293 SimTK_PLUGIN_XXX_MAKE_BODY(FuncName)(); \
294 } \
295 SimTK_PLUGIN_XXX_MAKE_SYMTEST(FuncName)
296
297#define SimTK_PLUGIN_DEFINE_FUNCTION1(RetType, FuncName, Arg1) \
298 typedef RetType (*FuncName##__Type__)(Arg1); \
299 SimTK_PLUGIN_XXX_MAKE_HOLDER(FuncName); \
300 RetType FuncName(Arg1 a1) const { \
301 SimTK_PLUGIN_XXX_MAKE_BODY(FuncName)(a1); \
302 } \
303 SimTK_PLUGIN_XXX_MAKE_SYMTEST(FuncName)
304
305#define SimTK_PLUGIN_DEFINE_FUNCTION2(RetType, FuncName, Arg1, Arg2) \
306 typedef RetType (*FuncName##__Type__)(Arg1,Arg2); \
307 SimTK_PLUGIN_XXX_MAKE_HOLDER(FuncName); \
308 RetType FuncName(Arg1 a1, Arg2 a2) const { \
309 SimTK_PLUGIN_XXX_MAKE_BODY(FuncName)(a1,a2); \
310 } \
311 SimTK_PLUGIN_XXX_MAKE_SYMTEST(FuncName)
312
313
314} // namespace SimTK
315
316#endif // SimTK_SimTKCOMMON_PLUGIN_H_
317
318
This file defines the Array_<T,X> class and related support classes including base classes ArrayViewC...
Declaration of the SimTK::Pathname class providing platform-independent manipulation of file pathname...
Mandatory first inclusion for any Simbody source or header file.
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:224
static std::string getAbsoluteDirectoryPathname(const std::string &dirPathname)
This is the same as getAbsolutePathname() except that the final segment is interpreted as a directory...
Definition: Pathname.h:209
This is the base class for representing a runtime-linked dynamic library, also known as a "plugin",...
Definition: Plugin.h:96
static bool deconstructLibraryName(const std::string &name, bool &isAbsolutePath, std::string &directory, std::string &libPrefix, std::string &baseName, std::string &debugSuffix, std::string &extension)
Dismantle a supplied library's file or pathname into its component parts.
static void unloadPlugin(void *handle)
Given a handle returned by loadPluginByFileName(), unload the plugin.
const std::string & getLoadedPathname() const
Definition: Plugin.h:126
Array_< std::string > m_searchPath
Definition: Plugin.h:250
static void * loadDebugOrReleasePlugin(const std::string &base, const std::string &extension, std::string &loadedFileName, std::string &errMsg)
If we're in Debug mode then this method attempts first to load the Debug version of the indicated lib...
void addSearchDirectory(const std::string &directory)
Add a directory to the end of the search path for this kind of plugin.
Definition: Plugin.h:150
void prependSearchDirectory(const std::string &directory)
Put a directory on the front of the search path for this kind of plugin.
Definition: Plugin.h:160
std::string m_defaultName
Definition: Plugin.h:249
void unload()
If a plugin is loaded, unload it now otherwise do nothing.
void setSearchPath(const Array_< std::string > &pathIn)
Provide a list of directories in the order you want them searched to find a plugin that was provided ...
Definition: Plugin.h:139
bool isLoaded() const
Is there currently a DLL associated with this Plugin object? If so you can call getLoadedPathname() t...
Definition: Plugin.h:124
const Array_< std::string > & getSearchPath() const
Definition: Plugin.h:145
void * m_handle
Definition: Plugin.h:253
static void * getSymbolAddress(void *handle, const std::string &name, std::string &errMsg)
If this fails the return value will be null and the system's human-readable error message is in errMs...
std::string getLastErrorMessage() const
If anything goes wrong the last error message is stored so you can retrieve it with this method.
Definition: Plugin.h:132
static void * loadPluginByFileName(const std::string &name, std::string &errMsg)
If this fails the return value will be null and the system's human-readable error message is in errMs...
Plugin(const std::string &defaultPathname="")
std::string m_lastMessage
Definition: Plugin.h:254
static std::string getDynamicLibDebugSuffix()
Obtain the appropriate debug suffix to use.
bool load(const std::string &name="")
Attempt to load a plugin of the given name if any, otherwise the default name (if any).
std::string m_loadedPathname
Definition: Plugin.h:252
static std::string getDynamicLibExtension()
This is the platform dependent extension (including the ".") used by default to identify dynamically ...
static std::string getDynamicLibPrefix()
This is the platform dependent string which gets prepended to a dynamic library baseName to form the ...
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37