comparison src/helper.cpp @ 10:c7baebf68fac

Some Win32 grossness
author Chris Cannam
date Tue, 03 May 2016 15:42:09 +0100
parents 25e00373f597
children 9f62684e1911
comparison
equal deleted inserted replaced
9:af46a17798be 10:c7baebf68fac
57 */ 57 */
58 58
59 #ifdef _WIN32 59 #ifdef _WIN32
60 #include <windows.h> 60 #include <windows.h>
61 #include <process.h> 61 #include <process.h>
62 #define DLOPEN(a,b) LoadLibrary((a).toStdWString().c_str()) 62 #include <string>
63 #define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b)) 63 #ifdef UNICODE
64 static HMODULE LoadLibraryUTF8(std::string name) {
65 int n = name.size();
66 wchar_t *wname = new wchar_t[n*2+1];
67 MultiByteToWideChar(CP_UTF8, 0, name.c_str(), n, wname, n*2);
68 HMODULE h = LoadLibraryW(wname);
69 delete[] wname;
70 return h;
71 }
72 static std::string GetErrorText() {
73 wchar_t *buffer;
74 DWORD err = GetLastError();
75 FormatMessage(
76 FORMAT_MESSAGE_ALLOCATE_BUFFER |
77 FORMAT_MESSAGE_FROM_SYSTEM |
78 FORMAT_MESSAGE_IGNORE_INSERTS,
79 NULL,
80 err,
81 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
82 (LPTSTR) &buffer,
83 0, NULL );
84 int n = wcslen(buffer);
85 char *text = new char[n*8 + 1];
86 WideCharToMultiByte(CP_UTF8, 0, buffer, n, text, n*8, 0, 0);
87 std::string s(text);
88 LocalFree(&buffer);
89 delete[] text;
90 for (int i = s.size(); i > 0; ) {
91 --i;
92 if (s[i] == '\n' || s[i] == '\r') {
93 s.erase(i, 1);
94 }
95 }
96 return s;
97 }
98 #define DLOPEN(a,b) LoadLibraryUTF8(a)
99 #else
100 #define DLOPEN(a,b) LoadLibrary((a).c_str())
101 #define GetErrorText() ""
102 #endif
103 #define DLSYM(a,b) (void *)GetProcAddress((HINSTANCE)(a),(b).c_str())
64 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) 104 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a)))
65 #define DLERROR() "" 105 #define DLERROR() (GetErrorText())
66 #else 106 #else
67 #include <dlfcn.h> 107 #include <dlfcn.h>
68 #define DLOPEN(a,b) dlopen((a).c_str(),(b)) 108 #define DLOPEN(a,b) dlopen((a).c_str(),(b))
69 #define DLSYM(a,b) dlsym((a),(b).c_str()) 109 #define DLSYM(a,b) dlsym((a),(b).c_str())
70 #define DLCLOSE(a) dlclose((a)) 110 #define DLCLOSE(a) dlclose((a))
78 118
79 using namespace std; 119 using namespace std;
80 120
81 string error() 121 string error()
82 { 122 {
83 string e = dlerror(); 123 string e = DLERROR();
84 if (e == "") return "(unknown error)"; 124 if (e == "") return "(unknown error)";
85 else return e; 125 else return e;
86 } 126 }
87 127
88 string check(string soname, string descriptor) 128 string check(string soname, string descriptor)
89 { 129 {
90 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); 130 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL);
91 if (!handle) { 131 if (!handle) {
92 return "Unable to open plugin library: " + error(); 132 return "Unable to open plugin library: " + error();
93 } 133 }
94 134
95 void *fn = DLSYM(handle, descriptor); 135 void *fn = DLSYM(handle, descriptor);
96 if (!fn) { 136 if (!fn) {
97 return "Failed to find plugin descriptor " + descriptor + 137 return "Failed to find plugin descriptor " + descriptor +
98 " in library: " + error(); 138 " in library: " + error();
99 } 139 }
100 140
101 return ""; 141 return "";
102 } 142 }
103 143
116 156
117 string descriptor = argv[1]; 157 string descriptor = argv[1];
118 158
119 while (getline(cin, soname)) { 159 while (getline(cin, soname)) {
120 string report = check(soname, descriptor); 160 string report = check(soname, descriptor);
121 if (report != "") { 161
162 if (report != "") {
122 cout << "FAILURE|" << soname << "|" << report << endl; 163 cout << "FAILURE|" << soname << "|" << report << endl;
123 allGood = false; 164 allGood = false;
124 } else { 165 } else {
125 cout << "SUCCESS|" << soname << "|" << endl; 166 cout << "SUCCESS|" << soname << "|" << endl;
126 } 167 }