1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup bli
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "BLI_dynlib.h"
31 
32 struct DynamicLibrary {
33   void *handle;
34 };
35 
36 #ifdef WIN32
37 #  define WIN32_LEAN_AND_MEAN
38 #  include "utf_winfunc.h"
39 #  include "utfconv.h"
40 #  include <windows.h>
41 
BLI_dynlib_open(const char * name)42 DynamicLibrary *BLI_dynlib_open(const char *name)
43 {
44   DynamicLibrary *lib;
45   void *handle;
46 
47   UTF16_ENCODE(name);
48   handle = LoadLibraryW(name_16);
49   UTF16_UN_ENCODE(name);
50 
51   if (!handle) {
52     return NULL;
53   }
54 
55   lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
56   lib->handle = handle;
57 
58   return lib;
59 }
60 
BLI_dynlib_find_symbol(DynamicLibrary * lib,const char * symname)61 void *BLI_dynlib_find_symbol(DynamicLibrary *lib, const char *symname)
62 {
63   return GetProcAddress(lib->handle, symname);
64 }
65 
BLI_dynlib_get_error_as_string(DynamicLibrary * lib)66 char *BLI_dynlib_get_error_as_string(DynamicLibrary *lib)
67 {
68   int err;
69 
70   /* if lib is NULL reset the last error code */
71   err = GetLastError();
72   if (!lib) {
73     SetLastError(ERROR_SUCCESS);
74   }
75 
76   if (err) {
77     static char buf[1024];
78 
79     if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
80                       NULL,
81                       err,
82                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
83                       buf,
84                       sizeof(buf),
85                       NULL)) {
86       return buf;
87     }
88   }
89 
90   return NULL;
91 }
92 
BLI_dynlib_close(DynamicLibrary * lib)93 void BLI_dynlib_close(DynamicLibrary *lib)
94 {
95   FreeLibrary(lib->handle);
96   MEM_freeN(lib);
97 }
98 
99 #else /* Unix */
100 
101 #  include <dlfcn.h>
102 
BLI_dynlib_open(const char * name)103 DynamicLibrary *BLI_dynlib_open(const char *name)
104 {
105   DynamicLibrary *lib;
106   void *handle = dlopen(name, RTLD_LAZY);
107 
108   if (!handle) {
109     return NULL;
110   }
111 
112   lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
113   lib->handle = handle;
114 
115   return lib;
116 }
117 
BLI_dynlib_find_symbol(DynamicLibrary * lib,const char * symname)118 void *BLI_dynlib_find_symbol(DynamicLibrary *lib, const char *symname)
119 {
120   return dlsym(lib->handle, symname);
121 }
122 
BLI_dynlib_get_error_as_string(DynamicLibrary * lib)123 char *BLI_dynlib_get_error_as_string(DynamicLibrary *lib)
124 {
125   (void)lib; /* unused */
126   return dlerror();
127 }
128 
BLI_dynlib_close(DynamicLibrary * lib)129 void BLI_dynlib_close(DynamicLibrary *lib)
130 {
131   dlclose(lib->handle);
132   MEM_freeN(lib);
133 }
134 
135 #endif
136