1 /***************************************************************************
2 cpluginmanager.cpp - description
3 -------------------
4 begin : Fri Sep 27 2002
5 copyright : (C) 2002-2003 by Mathias Küster
6 email : mathen@users.berlios.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "cpluginmanager.h"
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #ifndef WIN32
26 #include <dlfcn.h>
27 #endif
28
29 #include "core/cdir.h"
30 #include "cconfig.h"
31
32 /** */
CPluginManager()33 CPluginManager::CPluginManager()
34 {
35 m_pPluginList = new CList<CPluginObject>();
36 }
37
38 /** */
~CPluginManager()39 CPluginManager::~CPluginManager()
40 {
41 SetInstance(0);
42
43 delete m_pPluginList;
44 m_pPluginList = 0;
45 }
46
47 typedef ePluginStruct* (*PLUGIN_INIT_FUNC)();
48 typedef int (*PLUGIN_DEINIT_FUNC)();
49
50 /** */
Load(CString path)51 void CPluginManager::Load( CString path )
52 {
53 CDir dir;
54 CList<CFileInfo> list;
55 CFileInfo *fileinfo;
56 PLUGIN_INIT_FUNC dclib_plugin_init;
57 CPluginObject * Plugin;
58
59 #ifndef WIN32
60 void *h;
61 #else
62 HINSTANCE h;
63 #endif
64 // set default path
65 if ( path.IsEmpty() )
66 path = CConfig::Instance()->GetDCLibPluginPath();
67
68 /* Empty setting to disable plugin load */
69 if ( path.IsEmpty() )
70 return;
71
72 printf("Searching for plugins in '%s'\n", path.Data());
73
74 // set pluginpath
75 dir.SetPath(path);
76
77 // get all files
78 if ( dir.ReadEntrys( CDir::Files, &list ) )
79 {
80 fileinfo = 0;
81 while( (fileinfo=list.Next(fileinfo)) != 0 )
82 {
83 #ifdef WIN32
84 if ( dir.Extension(fileinfo->name).ToUpper() != "DLL" )
85 #else
86 if ( dir.Extension(fileinfo->name).ToUpper() != "SO" )
87 #endif
88 continue;
89
90 printf("Found plugin: '%s'\n",fileinfo->name.Data());
91
92 #ifdef WIN32
93 if ( (h = LoadLibraryEx((path+DIRSEPARATOR+fileinfo->name).Data(),NULL,0)) == NULL )
94 {
95 #else
96 if ( (h = dlopen( (path+DIRSEPARATOR+fileinfo->name).Data(), RTLD_LAZY )) == NULL )
97 {
98 printf("Error dlopen %s\n",dlerror());
99 #endif
100 continue;
101 }
102
103 /* The "fix" for the warning:
104 *
105 * ISO C++ forbids casting between pointer-to-function and pointer-to-object
106 *
107 * as documented in dlopen(3) does not appear to make much
108 * sense and generates a:
109 *
110 * dereferencing type-punned pointer will break strict-aliasing rules
111 *
112 * warning but we already have plenty of those. Trying other things
113 * like reinterpret_cast is no help.
114 */
115 #ifdef WIN32
116 dclib_plugin_init = (PLUGIN_INIT_FUNC) GetProcAddress(h,"dclib_plugin_init");
117 #else
118 *(void**) (&dclib_plugin_init) = dlsym(h, "dclib_plugin_init");
119 #endif
120
121 if ( dclib_plugin_init == NULL )
122 {
123 #ifndef WIN32
124 printf("Error dlsym %s\n",dlerror());
125 dlclose(h);
126 #else
127 FreeLibrary(h);
128 #endif
129 }
130 else
131 {
132 Plugin = new CPluginObject();
133 Plugin->m_sFileName = path + fileinfo->name;
134
135 Plugin->m_Handle = h;
136 Plugin->m_ePluginStruct = dclib_plugin_init();
137
138 Plugin->m_ePluginStruct->init();
139
140 //ps->deinit();
141
142 /*
143 if ( Plugin->m_eType == eptNONE )
144 {
145 printf("Error init plugin\n");
146 #ifndef WIN32
147 dlclose(h);
148 #else
149 FreeLibrary(h);
150 #endif
151 delete Plugin;
152 continue;
153 }
154 */
155 m_pPluginList->Add(Plugin);
156 }
157 }
158 }
159 }
160
161 /** */
162 void CPluginManager::InitPlugins()
163 {
164 CPluginObject * plugin = 0;
165
166 while ( (plugin = m_pPluginList->Next(plugin)) != 0 )
167 {
168 if ( Init(plugin) == false )
169 {
170 printf("Init Failed\n");
171 }
172 }
173 }
174
175 /** */
176 void CPluginManager::DeInitPlugins()
177 {
178 CPluginObject * plugin = 0;
179
180 while ( (plugin = m_pPluginList->Next(0)) != 0 )
181 {
182 plugin->m_ePluginStruct->deinit();
183
184 #ifndef WIN32
185 dlclose(plugin->m_Handle);
186 #else
187 FreeLibrary(plugin->m_Handle);
188 #endif
189 m_pPluginList->Remove(plugin);
190 delete plugin;
191 }
192 }
193
194 /** */
195 bool CPluginManager::Init( CPluginObject * plugin )
196 {
197 if ( plugin->m_ePluginStruct->m_eType != eptLIB )
198 {
199 printf("Plugin != LIB not for me ...\n");
200 return false;
201 }
202
203 return true;
204 }
205