ComSDK
 Указатель Классы Пространства имен Функции Переменные Определения типов Перечисления Элементы перечислений Друзья Группы Страницы
libtools.h
1 //===========================================================================
2 #ifndef comfrm_LibSupportH
3 #define comfrm_LibSupportH
4 //===========================================================================
5 // Заготовка модуля LibSupport была сгенерирована CASE средством разработки SA2-DE.
6 // Все права защищены. (2010)
7 //
8 // В данном файле представлен исходный текст основного заголовочного файла модуля.
9 //
10 // ======================================= //
11 // Параметры новой разработки.
12 // ======================================= //
13 // Имя комплекса: CommonTools (com)
14 // Имя решения: GCAD_3 (gc3) (прочерк если модуль относится лишь к комплексу)
15 // Имя проекта: System (sys) (прочерк если модуль относится лишь к решению)
16 // Полный SID: comgc3sys
17 // Время создания: 20:34:55
18 // Дата создания: 04.12.2010
19 // ======================================= //
20 // ============================================================================================ //
21 // Параметры ревизии(версии):
22 // ============================================================================================ //
23 // [prd]Period: 12/2010
24 // [aut]Author: Александр Соколов
25 // [did]DeveloperID: sa
26 // [pid]ProblemID: 00001
27 // [rvs = did.date.pid]Revision: //#sa.04.12.2010.00001
28 // [dsc]Description: Поддержка библиотек
29 // [ccm]CodeComment: rvs.{[s]Start | [e]End | []}{[n]New | [o]Old | [d]Develop}
30 // ============================================================================================ //
31 // [prd]Period: 08/2012
32 // [aut]Author: Юрин Юрий
33 // [did]DeveloperID: yu
34 // [pid]ProblemID: 00002
35 // [rvs = did.date.pid]Revision: //#yu.08.04.2012.00002
36 // [dsc]Description: Добавил класс-обертку над загрузчиком библиотеки. Он позволит
37 // решить проблему загрузки нескольких функций региcтрации из одной DLL
38 // [ccm]CodeComment: rvs.{[s]Start | [e]End | []}{[n]New | [o]Old | [d]Develop}
39 // ============================================================================================ //
40 // [prd]Period: 04/2012
41 // [aut]Author: Александр Соколов
42 // [did]DeveloperID: sa
43 // [pid]ProblemID: 00003
44 // [rvs = did.date.pid]Revision: //#sa.15.04.2012.00003
45 // [dsc]Description: Портирование решателей в Linux. Доработка кода для кроссплатформенной компиляции.
46 // [ccm]CodeComment: rvs.{[s]Start | [e]End | []}{[n]New | [o]Old | [d]Develop}
47 // ============================================================================================ //
48 // [prd]Period: 11/2012
49 // [aut]Author: Вячеслав Макаренков
50 // [did]DeveloperID: mv
51 // [pid]ProblemID: 00004
52 // [rvs = did.date.pid]Revision: //#mv.09.11.2012.00004
53 // [dsc]Description: Добавил функцию освобождения ресурсов при загрузке функции ( не объекта )
54 // [ccm]CodeComment: rvs.{[s]Start | [e]End | []}{[n]New | [o]Old | [d]Develop}
55 // ============================================================================================ //
56 // [prd]Period: 03/2013
57 // [aut]Author: Александр Соколов
58 // [did]DeveloperID: sa
59 // [pid]ProblemID: 00005
60 // [rvs = did.date.pid]Revision: //#sa.10.03.2013.00005
61 // [dsc]Description: доработка - обработка случая "экспорта" из LIB
62 // [ccm]CodeComment: rvs.{[s]Start | [e]End | []}{[n]New | [o]Old | [d]Develop}
63 // ============================================================================================ //
64 //========================================================================
65 // ДОПОЛНИТЕЛЬНЫЕ ПОДКЛЮЧЕНИЯ (Типы и модули, необходимые для .h - файла)
66 //------------------------------------------------------------------------
67 #include "memorytools.h"
68 
69 #include <string>
70 #include <iostream>
71 
72 #if defined _WIN32
73  #include <windows.h>
74  #if defined(_WINDLL)
75  #define MAC_DLLEXPORT __declspec(dllexport)
76  #define MAC_DLLEXPORT_FROMEXE __declspec(dllimport)
77  #else
78  #define MAC_DLLEXPORT __declspec(dllimport)
79  #define MAC_DLLEXPORT_FROMEXE __declspec(dllexport)
80  #endif
81  typedef HMODULE DllHandle;
82 #elif defined __linux__
83  #include <dlfcn.h>
84  #define MAC_DLLEXPORT
85  #define MAC_DLLEXPORT_FROMEXE
86  typedef void* DllHandle;
87 #endif
88 
89 //========================================================================
90 namespace com
91 {
100  namespace lib
101  {
109  template<class TDllHandle>
110  int loadLibrary(const std::string& p_dllname, TDllHandle& o_dll)
111  {
112  int res = 0;
113 
114 #if defined _WIN32
115  o_dll = LoadLibrary(p_dllname.c_str());
116 #elif defined __linux__
117  // Особенность dlopen -- чтобы загрузить библ., находящуюся
118  // в текущей директории, нужно задать имя ./libname.so
119  std::string dllName(p_dllname);
120  std::string libName;
121  std::string path;
122 
123  // Проверяем, содержится ли в p_dllname только одно имя без пути
124  int lastSlashPos = dllName.find_last_of('/');
125  if (lastSlashPos != std::string::npos)
126  {
127  path = dllName.substr(0, lastSlashPos);
128  libName = dllName.substr(lastSlashPos + 1);
129  }
130  else
131  {
132  path = ".";
133  libName = dllName;
134  }
135 
136  // Приводим имя к общему стандарту: ./libname.so или path1/path2/path3/libname.so
137  // Если при этом задано некоторое расширение, сохраняем его
138  if (libName.find_last_of('.') == std::string::npos)
139  libName += ".so";
140 
141  if (libName.substr(0, 3) != "lib")
142  libName = "lib" + libName;
143 
144  std::string prettyLibName = path + "/" + libName;
145  o_dll = dlopen(prettyLibName.c_str(),RTLD_LAZY);
146 #endif
147  if (o_dll == 0)
148  {
149  std::cerr << "Не удалось загрузить DLL (-1):" << p_dllname << std::endl;
150 #if defined __linux__
151  std::cerr << dlerror() << std::endl;
152 #endif
153  res = -1;
155  }
156 
157  return res;
158  }
159 
166  template<class FunctionType, class TDllHandle>
167  FunctionType* loadFunction(TDllHandle p_dll, const std::string& p_regfunc)
168  {
169  FunctionType* reg = NULL;
170 #if defined _WIN32
171  reg = (FunctionType*) GetProcAddress(p_dll, p_regfunc.c_str());
172 #elif defined __linux__
173  reg = (FunctionType*) dlsym(p_dll, p_regfunc.c_str());
174 #endif
175  if (reg == 0)
176  {
177  std::cerr << "Не удалось найти функцию:" << p_regfunc << std::endl;
178 #if defined __linux__
179  std::cerr << dlerror() << std::endl;
180 #endif
181  return NULL;
182  }
183 
184  return reg;
185  }
186 
194  template< class FunctionType, class TDllHandle >
195  FunctionType* loadFunction(const std::string& p_dllname, const std::string& p_regfunc,
196  TDllHandle& o_dll)
197  {
198  int res = loadLibrary< TDllHandle >(p_dllname, o_dll);
199 
201  return loadFunction< FunctionType >(o_dll, p_regfunc);
202  }
203 
208  template< class TDllHandle >
209  void unloadLibrary(TDllHandle p_dll)
210  {
211 #if defined _WIN32
212  FreeLibrary(p_dll);
213 #elif defined __linux__
214  dlclose(p_dll);
215 #endif
216  }
217 
224  template< class OutClass >
225  OutClass* registerObject(void* p_func, const std::string& p_input_file = "")
226  {
227  typedef OutClass* ftyp1(const char*);
228  typedef OutClass* ftyp2();
229  if (p_func != 0)
230  {
231  if (p_input_file != "")
232  return ((ftyp1*) p_func)(p_input_file.c_str());
233  else
234  return ((ftyp2*) p_func)();
235  }
236  else
237  return NULL;
238  }
239 
248  template< class OutClass, class TDllHandle >
249  OutClass* registerObject(const std::string& p_dllname, const std::string& p_regfunc,
250  TDllHandle& o_dll, const std::string& p_input_file = "")
251  {
252  void* reg = loadFunction< void, TDllHandle >(p_dllname, p_regfunc, o_dll);
253 
255  return registerObject< OutClass >(reg, p_input_file);
256  }
257 
266  template< class OutClass, class InputParam, class TDllHandle >
267  OutClass* registerQualifiedObject(const std::string& p_dllname, const std::string& p_regfunc,
268  TDllHandle& o_dll, const InputParam& p_input_data)
269  {
270  typedef OutClass* ftyp1(const InputParam&);
271  ftyp1* reg = loadFunction< ftyp1, TDllHandle >(p_dllname, p_regfunc, o_dll);
272  if (reg != 0)
273  return reg(p_input_data);
274  else
275  return NULL;
276  }
277 
283  template< class OutClass, class TDllHandle >
284  void unregisterObject(OutClass* p_obj, TDllHandle p_dll)
285  {
286  MAC_MEMRELEASE(p_obj);
287  if (p_dll)
288  {
289 #if defined _WIN32
290  FreeLibrary(p_dll);
291 #elif defined __linux__
292  dlclose(p_dll);
293 #endif
294  }
295  }
296 
301  template< class TDllHandle >
302  class DllLoader
303  {
305  TDllHandle mDLL;
307  bool mError;
308 
309  public:
310  bool isError()
311  {
312  return mError;
313  }
314 
315  DllLoader(const std::string& p_dll_name)
316  {
318  int res = loadLibrary< TDllHandle >(p_dll_name, mDLL);
319 
321  mError = !mDLL;
322  }
323 
324  template< typename OutObjectType >
325  int createObject(const char* p_reg_func_name, OutObjectType*& o_obj, const std::string& p_input_file = "")
326  {
327  void* reg = loadFunction< void >(mDLL, p_reg_func_name);
328  o_obj = registerObject< OutObjectType >(reg, p_input_file);
329  int res = 0;
330  if (o_obj == NULL)
331  {
333  res = -1;
334  }
335 
336  return res;
337  }
338 
339  ~DllLoader()
340  {
341  if (!mError)
342  FreeLibrary(mDLL);
343  }
344  };
345  };
346 };
347 
348 
349 //===========================================================================
350 #endif
351 //===========================================================================
OutClass * registerObject(void *p_func, const std::string &p_input_file="")
Definition: libtools.h:225
int loadLibrary(const std::string &p_dllname, TDllHandle &o_dll)
Definition: libtools.h:110
OutClass * registerQualifiedObject(const std::string &p_dllname, const std::string &p_regfunc, TDllHandle &o_dll, const InputParam &p_input_data)
Definition: libtools.h:267
void unregisterObject(OutClass *p_obj, TDllHandle p_dll)
Definition: libtools.h:284
FunctionType * loadFunction(TDllHandle p_dll, const std::string &p_regfunc)
Definition: libtools.h:167
#define MAC_MEMRELEASE(A)
Definition: memorytools.h:58
int createObject(const char *p_reg_func_name, OutObjectType *&o_obj, const std::string &p_input_file="")
Definition: libtools.h:325
void unloadLibrary(TDllHandle p_dll)
Definition: libtools.h:209
DllLoader(const std::string &p_dll_name)
Definition: libtools.h:315
Класс для загрузки библиотек и получения объектов из них
Definition: libtools.h:302