Field3D
PluginLoader.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2009 Sony Pictures Imageworks Inc
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution. Neither the name of Sony Pictures Imageworks nor the
18 * names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36//----------------------------------------------------------------------------//
37
42//----------------------------------------------------------------------------//
43
44#ifdef WIN32
45#define WIN32_LEAN_AND_MEAN
46#include <windows.h>
47#else
48#include <dlfcn.h>
49#include <dirent.h>
50#endif
51
52#include <sys/types.h>
53#include <stdlib.h>
54#include <string>
55#include <vector>
56#include <stdio.h>
57#include <errno.h>
58#include <string.h>
59
60#include <boost/tokenizer.hpp>
61
62#include "ClassFactory.h"
63#include "PluginLoader.h"
64
65//----------------------------------------------------------------------------//
66
67using namespace std;
68
69//----------------------------------------------------------------------------//
70// Local namespace
71//----------------------------------------------------------------------------//
72
73namespace {
74
75 void tokenize(const std::string &str, const std::string &delimiters,
76 std::vector<std::string> &retItems)
77 {
78 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
79 boost::char_separator<char> sep(delimiters.c_str());
81 for (Tokenizer::iterator i = tok.begin(); i != tok.end(); ++i) {
82 retItems.push_back(*i);
83 }
84 }
85
86}
87
88//----------------------------------------------------------------------------//
89
91
93
94
95//----------------------------------------------------------------------------//
96// Static instances
97//----------------------------------------------------------------------------//
98
99std::vector<std::string> PluginLoader::ms_pluginsLoaded;
100
101//----------------------------------------------------------------------------//
102// PluginLoader implementations
103//----------------------------------------------------------------------------//
104
105static int filter(std::string &name, const char *suffix)
106{
107 std::string delimiters = ".";
108 std::vector <std::string> items;
109
110 tokenize(name, delimiters, items);
111
112 if (items.size() == 0) {
113 return 0;
114 }
115
116 if (items[items.size() -1] == suffix) {
117 return 1;
118 }
119
120 return 0;
121}
122
123//----------------------------------------------------------------------------//
124
125bool getDirSos(std::vector<std::string> &sos, std::string &dir)
126{
127#ifdef WIN32
128 const char *ds = dir.c_str();
129 HANDLE dirh;
131
133 while (dirh != INVALID_HANDLE_VALUE)
134 {
135 std::string name = fd.cFileName;
136 std::string name_lower;
137
138 std::transform(name.begin(), name.end(), name_lower.begin(), ::tolower);
139
140 if (filter(name_lower, "so")) {
141 name = dir + "/" + name;
142 sos.push_back(name);
143 }
144
145 if (!FindNextFileA(dirh, &fd))
146 {
148 break;
149 }
150 }
151#else
152 struct dirent *dirent;
153
154 const char *ds = dir.c_str();
155 DIR *dirfd = opendir(ds);
156 if (!dirfd) {
157 std::string er =
158 "Field3D_plugin loader: could not open directory " + dir + "\n";
159 //perror(er.c_str());
160 return false;
161 }
162
164 while (dirent != NULL) {
165
166 std::string name = dirent->d_name;
167
168 if (filter(name, "so")) {
169 name = dir + "/" + name;
170 sos.push_back(name);
171 }
172
174 }
175
177#endif
178 return true;
179}
180
182{
183#ifdef WIN32
185#else
186 void *handle = dlopen(sofile.c_str(), RTLD_GLOBAL|RTLD_NOW);
187#endif
188 // Attempt to load .so file
189 if (!handle) {
190 std::string errmsg;
191#ifdef WIN32
192 char *errstr;
193//----------------------------------------------------------------------------//
195 NULL, GetLastError(),
197 0, NULL);
198 if (errstr) {
199 errmsg = errstr;
201 } else {
202 errmsg = "Unknown error";
203 }
204#else
205 errmsg = dlerror();
206#endif
207
208 std::cout <<
209 "Field3D Plugin loader: failed to load plugin: " << errmsg << "\n";
210 return 0;
211 }
212
213 // Determine plugin type by looking for one of:
214 // registerField3DPlugin()
215
217
218#ifdef WIN32
219 fptr = (RegistrationFunc)GetProcAddress(handle,"registerField3DPlugin");
220#else
221 fptr = (RegistrationFunc)dlsym(handle,"registerField3DPlugin");
222#endif
223 if (!fptr) {
224 char *debugEnvVar = getenv("FIELD3D_DEBUG");
225 if (debugEnvVar) {
226 // debug env var exist, so print warning
228 "Field3D plugin loader: failed to load "
229 "the symbol registerField3DPlugin");
230 }
231 }
232 return fptr;
233}
234
235
236//----------------------------------------------------------------------------//
237
242
243//----------------------------------------------------------------------------//
244
249
250//----------------------------------------------------------------------------//
251
253{
254 // Get environment variable
255 char *cptr = getenv("FIELD3D_DSO_PATH");
256 if (!cptr)
257 return;
258
259 std::string path = cptr;
260
261 // Split paths
262 std::vector<std::string> paths;
263 const std::string delimiters = ":";
264
266
267 // For each path
268 for (unsigned int i = 0; i < paths.size(); i++) {
269
270 // List the contents of the directory
271 std::vector<std::string> sos;
272 if (!getDirSos(sos,paths[i])) {
273 continue;
274 }
275
276 // Open each file
277 for (unsigned int j = 0; j < sos.size(); j++) {
278 std::string sofile = sos[j];
279
280 //First check to see if a plugin of the same name has already been loaded
281 const std::string pathDelimiter = "/";
282 std::vector<std::string> pluginName;
284
285 bool pluginAlreadyLoaded = false;
286
287 for (unsigned int i = 0; i < ms_pluginsLoaded.size(); i++) {
288 if (pluginName.size() > 0) {
289 if (ms_pluginsLoaded[i] == pluginName[pluginName.size() - 1]) {
290 //This plugin has been loaded so look for another one
291 //std::cout << ms_pluginsLoaded[i] << " is already loaded\n";
292 pluginAlreadyLoaded = true;
293 break;
294 }
295 }
296 }
297
299 continue;
300 }
301
302 if (pluginName.size() > 0) {
303 std::string lastName = pluginName[pluginName.size() -1];
304 ms_pluginsLoaded.push_back(lastName);
305 }
306
308
310 if (fptr) {
311 // Call the registration function
312 int res = (*fptr)(ClassFactory::singleton());
313 if (!res) {
315 "failed to init Field3D plugin " + sofile);
316 } else {
317 Msg::print("Initialized Field3D Plugin " + sofile);
318 }
319 }
320 }
321 }
322}
323
324//----------------------------------------------------------------------------//
325
326#if 0
327
328bool PluginLoader::getDso(char *cptr, const char *dso,
329 std::string &dsoPath)
330{
331
332 std::string path = cptr;
333
334 // Split paths
335 std::vector<std::string> paths;
336 const std::string delimiters=":";
337
339
340 // For each path
341 for (unsigned int i=0; i < paths.size(); i++) {
342 struct dirent *dirent;
343
344 std::string dir = paths[i];
345 const char *ds = dir.c_str();
346 DIR *dirfd = opendir(ds);
347 if (!dirfd) {
348 continue;
349 }
350
352 while (dirent != NULL) {
353
354 std::string name = dirent->d_name;
355
356 if (name == dso) {
357 dsoPath = dir + "/" + name;
359 return true;
360 }
361
363 }
365 }
366
367
368 return false;
369
370}
371
372//----------------------------------------------------------------------------//
373
374bool PluginLoader::resolveGlobalsForPlugins(const char *dso) {
375
376 // Get environment variable
377 char *cptr = getenv("HOUDINI_DSO_PATH");
378 if (!cptr)
379 return false;
380
381 std::string sofile;
382 if (!getDso(cptr,dso,sofile)) {
383 std::string dsostring = dso;
384 Msg::print(dsostring + " is not in HOUDINI_DSO_PATH");
385 return false;
386 }
387
388 void *handle = dlopen(sofile.c_str(), RTLD_GLOBAL|RTLD_NOW);
389
390 if (!handle) {
391 std::cout << "Field3D Plugin loader: failed to load Houdini plugin: "
392 << sofile << " " << dlerror() << "\n";
393 return false;
394 }
395
396#if 0
397 Msg::print("---------------------------------------------------------");
398 Msg::print("Loaded " + sofile);
399 Msg::print("---------------------------------------------------------");
400#endif
401
402 return true;
403
404}
405
406#endif
407
408//----------------------------------------------------------------------------//
409
411
412//----------------------------------------------------------------------------//
Contains the ClassFactory class for registering Field3D classes.
bool getDirSos(std::vector< std::string > &sos, std::string &dir)
static RegistrationFunc findRegistrationFunc(const std::string &sofile)
static int filter(std::string &name, const char *suffix)
FIELD3D_NAMESPACE_OPEN typedef int(* RegistrationFunc)(ClassFactory &)
Contains the PluginLoader class.
bool getDirSos(std::vector< std::string > &sos, std::string &dir)
#define FIELD3D_MTX_T
Definition StdMathLib.h:99
static ClassFactory & singleton()
}
PluginLoader()
Default constructor.
~PluginLoader()
Destructor.
static std::vector< std::string > ms_pluginsLoaded
List of plugins loaded.
static void loadPlugins()
Checks all paths in $FIELD3D_DSO_PATH and loads the plugins it finds.
@ SevWarning
Definition Log.h:68
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity.
Definition Log.cpp:70
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60