SharedLibrary.hpp revision 2a1c5693e8fab2cb4c7e087e16a49c91fca9ce7f
1// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2012 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#ifndef SharedLibrary_hpp
13#define SharedLibrary_hpp
14
15#if defined(_WIN32)
16	#include <Windows.h>
17#else
18	#include <dlfcn.h>
19#endif
20
21void *getLibraryHandle(const char *path);
22void *loadLibrary(const char *path);
23void freeLibrary(void *library);
24void *getProcAddress(void *library, const char *name);
25
26template<int n>
27void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullptr)
28{
29	for(int i = 0; i < n; i++)
30	{
31		void *library = getLibraryHandle(names[i]);
32
33		if(library)
34		{
35			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
36			{
37				return library;
38			}
39
40			freeLibrary(library);
41		}
42	}
43
44	for(int i = 0; i < n; i++)
45	{
46		void *library = loadLibrary(names[i]);
47
48		if(library)
49		{
50			if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
51			{
52				return library;
53			}
54
55			freeLibrary(library);
56		}
57	}
58
59	return 0;
60}
61
62#if defined(_WIN32)
63	inline void *loadLibrary(const char *path)
64	{
65		return (void*)LoadLibrary(path);
66	}
67
68	inline void *getLibraryHandle(const char *path)
69	{
70		HMODULE module = 0;
71		GetModuleHandleEx(0, path, &module);
72		return (void*)module;
73	}
74
75	inline void freeLibrary(void *library)
76	{
77		FreeLibrary((HMODULE)library);
78	}
79
80	inline void *getProcAddress(void *library, const char *name)
81	{
82		return (void*)GetProcAddress((HMODULE)library, name);
83	}
84#else
85	inline void *loadLibrary(const char *path)
86	{
87		return dlopen(path, RTLD_LAZY);
88	}
89
90	inline void *getLibraryHandle(const char *path)
91	{
92		#ifdef __ANDROID__
93			// bionic doesn't support RTLD_NOLOAD before L
94			return dlopen(path, RTLD_NOW);
95		#else
96			void *resident = dlopen(path, RTLD_LAZY | RTLD_NOLOAD);
97
98			if(resident)
99			{
100				return dlopen(path, RTLD_LAZY);   // Increment reference count
101			}
102
103			return 0;
104		#endif
105	}
106
107    inline void freeLibrary(void *library)
108    {
109        if(library)
110        {
111            dlclose(library);
112        }
113    }
114
115	inline void *getProcAddress(void *library, const char *name)
116	{
117		return library ? dlsym(library, name) : 0;
118	}
119#endif
120
121#endif   // SharedLibrary_hpp
122