-
Notifications
You must be signed in to change notification settings - Fork 375
/
Copy pathgmt_sharedlibs.c
114 lines (98 loc) · 3.31 KB
/
gmt_sharedlibs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Copyright (c) 2012-2025 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
* See LICENSE.TXT file for copying and redistribution conditions.
*/
/* Here are Windows implementations of standard POSIX shared
* library function. Borrowed from this website:
* http://www.refcode.net/2013/02/posix-dynamic-library-loading-calls-for.html
* which says it is open source.
*/
#include "gmt_dev.h"
#include "gmt_sharedlibs.h" /* Common shared libs structures */
#if defined(_WIN32)
void *dlopen (const char *module_name, int mode) { /* Opens a dll file*/
UINT err_code;
HINSTANCE dll_handle;
gmt_M_unused (mode);
err_code = SetErrorMode (SEM_FAILCRITICALERRORS);
dll_handle = LoadLibrary (module_name);
if (!dll_handle) {
dll_handle = LoadLibraryEx (module_name, NULL, 0);
if (!dll_handle)
return (void *)dll_handle;
}
/* Clear the last error*/
SetLastError (0);
return (void *)dll_handle;
}
int dlclose (void *handle) {
/* Closes handle */
/* POSIX call returns zero for success, non-zero for failure */
return (!FreeLibrary (handle));
}
void *dlsym (void *handle, const char *name) {
/* Get a symbol from dll */
return GetProcAddress (handle, name);
}
char *dlerror (void) {
/* Reports last error occurred */
int len, error_code;
static char errstr[GMT_LEN128];
if ((error_code = GetLastError ()) == 0)
return NULL;
/* POSIX dlerror call needs to report no error (null)
when it is called 2nd time consequently, so clear error */
SetLastError (0);
/* Format the error string */
len = snprintf (errstr, GMT_LEN128, "Error <%d>: ", error_code);
len += FormatMessage (
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) errstr + len,
sizeof(errstr) - len,
NULL
);
/* Replace \r\n */
if (len > 1 && errstr[len-2] == '\r' && errstr[len-1] == '\n') {
if (len > 2 && errstr[len-3] == '.')
len--;
}
return errstr;
}
/* Extra convenience function for opening DLL of current process */
HINSTANCE GetMyModuleHandle() {
/* http://stackoverflow.com/questions/846044/how-to-get-the-filename-of-a-dll */
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(GetMyModuleHandle, &mbi, sizeof(mbi));
return (HINSTANCE) (mbi.AllocationBase);
}
void *dlopen_special(const char *name) {
/* Opens the dll file of the current process. This is how it is done
* under Windows, per http://en.wikipedia.org/wiki/Dynamic_loading */
/*HMODULE this_process, this_process_again;
GetModuleHandleEx (0, 0, &this_process);
this_process_again = GetModuleHandle (NULL);
return (this_process_again);*/
gmt_M_unused (name);
HINSTANCE this_dll_process;
this_dll_process = GetMyModuleHandle();
return (this_dll_process);
}
#elif defined(__CYGWIN__)
/* Cygwin behaves differently than most Unix and we must use regular dlopen with library name */
void *dlopen_special(const char *name) {
/* Opens the shared library file of the current process under *nix.
* Just call dlopen with NULL and RTLD_LAZY */
return (dlopen (name, RTLD_LAZY));
}
#else
/* Extra convenience function for opening shared library of current process */
void *dlopen_special(const char *name) {
/* Opens the shared library file of the current process under *nix.
* Just call dlopen with NULL and RTLD_LAZY */
gmt_M_unused(name);
return (dlopen (NULL, RTLD_LAZY));
}
#endif