| The Gaudi Framework v29r1 (5cd95fa2)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

GaudiPluginService/doc/README.md
Go to the documentation of this file.
1 Gaudi Plugin Service Instructions {#GaudiPluginService-readme}
2 ==================================
3
4 Introduction
5 ------------
6
7 The Gaudi Plugin Service is a small tool to add to a C++ application the
8 possibility of dynamically instantiate (via _factories_) objects from classes
9 defined in plug-in (or component) libraries.
10
11 While being part of Gaudi, it only depends on a Posix system (support for other
12 systems is possible, but very low priority).
13
14
15 Usage
16 ------
17
18 To be able to use plug-ins from an application you need:
19
20 - a base class (abstract or not) from a library
21 - a library that provides a class that inherits from the base class
22
23 In the base class you should declare the signature of the the factory for your
24 derived classes. For example, if your base class is called `Foo` and you want
25 to instantiate the derived classes with one `std::string` argument, you can
26 write something like:
27
28 #include <Gaudi/PluginService.h>
29 #include <string>
30 class Foo {
31 public:
32 typedef Gaudi::PluginService::Factory1<Foo*, const std::string&> Factory;
33
34 /// Constructor
35 Foo(const std::string& name);
36
37 // ...
38 };
39
40 The templated class `Gaudi::PluginService::Factory1` takes as first template
41 argument the return type of the factory and as second argument the type of the
42 first argument of the factory function (with all the required qualifiers
43 explicit). There are several variants of the class for different number of
44 arguments required by the constructor (`Factory0`, `Factory1`, `Factory2`, ...).
45
46 The plug-in class `Bar` defined in the dynamically loaded library will require
47 a declaration to the Plugin Service to use it, so in the source file you have to
48 have something like:
49
50 #include "Bar.h"
51 DECLARE_COMPONENT(Bar)
52
53 The library with `Foo` and the library with `Bar` will have to be linked against
54 the library `libGaudiPluginService.so`.
55
56 To enable the automatic discovery of plugins, the library with `Bar` must be
57 processed by the program `listcomponents` and the output must be stored in a
58 file with extension `.comonents` in a directory in the `LD_LIBRARY_PATH`.
59 For example, if the `lib` directory contains `libBar.so` and it is specified in
60 the `LD_LIBRARY_PATH`, you can call the commands:
61
62 listcomponents libBar.so >> lib/MyApp.components
63
64 Note that the `.components` file does not need to be in the same directory as
65 `libBar.so`.
66
67 The application code, linked against the library providing `Foo` can now
68 instantiate objects of class `Bar` like this:
69
70 #include "Foo.h"
71
72 // ...
73 Foo* myBar = Foo::Factory::create("Bar", "myBar");
74 // ...
75
76 where the first argument to the function `create` is the name of the class you
77 want to instantiate, and the other arguments are passed to the constructor of
78 the class.
79
80
81 Special cases
82 -------------
83
84 ### Factory aliases
85
86 Together with the simple usage described above, the Gaudi Plugin Service allows
87 you to give to use aliases to refer to the plug-in class.
88 For example, for a templated plug-in class you may have:
89
90 #include "TemplatedBar.h"
91 typedef TemplatedBar<int, std::vector<double> > MyBar;
92 DECLARE_COMPONENT(MyBar)
93
94 but to instantiate it you must call
95
96 Foo* b = Foo::Factory::create("TemplatedBar<int, std::vector<double> >",
97 "MyTemplatedBar");
98
99 Which is error prone and unreadable, but you can declare the component class
100 with and _id_ (an alias):
101
102 DECLARE_COMPONENT_WITH_ID(MyBar, "MyBar")
103
104 (note that the _id_ must support the `<<` operator of `std::ostream`).
105 The call in the application becomes:
106
107 Foo* b = Foo::Factory::create("MyBar", "MyTemplatedBar");
108
109
110 ### Namespaces
111
112 You cannot use namespace delimiters in the call to `DECLARE_COMPONENT`, but you
113 can still use namespaces for you component classes. For example, if you have the
114 class `Baz::Fun` you can declare it as a component class in any of the following
115 ways:
116
117 using Baz::Fun;
118 DECLARE_COMPONENT(Fun)
119
120 namespace Baz {
121 DECLARE_COMPONENT(Fun)
122 }
123
124 typedef Baz::Fun BF;
125 DECLARE_COMPONENT(BF)
126
127 In all cases the name of the factory to be passed to the `create` function will
128 be "Baz::Fun".