-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathwrapper.h
More file actions
160 lines (132 loc) · 3.66 KB
/
wrapper.h
File metadata and controls
160 lines (132 loc) · 3.66 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
wrapper.cpp -- an ultimate VInterface wrapper for Source Tegra port
Copyright (C) 2017 a1batross
Licensed under WTFPL license.
Thanks to Valve for SDK, me for idea.
Please, don't punish, Mr. Newell. :)
*/
#pragma once
#include <stdlib.h>
#ifdef ANDROID
#include <dlfcn.h>
#include <android/log.h>
#include <stdio.h>
#define TAG "SourceSDK2013"
#define PRIO ANDROID_LOG_DEBUG
#define LogPrintf(...) do { __android_log_print(PRIO, TAG, __VA_ARGS__); printf( __VA_ARGS__); } while( 0 );
#else
#include <stdio.h>
#define LogPrintf(...) printf(__VA_ARGS__)
#endif
// don't link tier1
#include "Interface/interface.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#define LogDebug(str) OutputDebugString(str)
#endif
#undef DLLEXPORT
#define DLLEXPORT extern "C" __attribute__((visibility("default")))
class Module
{
public:
Module() : m_szName(NULL), m_pLibrary(NULL), CreateInterface(NULL) {}
~Module() { Unload(); }
bool Load(const char* name, bool isModule = true)
{
m_szName = name;
m_pLibrary = Sys_LoadModule(name);
if (!m_pLibrary)
{
#ifdef POSIX
LogPrintf("Module::Load: Failed to load %s: %s\n", name, dlerror());
#else
LogPrintf("Module::Load: Failed to load %s: %d\n", name, GetLastError());
#endif
return false;
}
if (isModule)
{
CreateInterface = (void* (*)(const char*, int*))Resolve("CreateInterface");
if (!CreateInterface)
{
return false;
}
}
return true;
}
void Unload()
{
if (m_pLibrary)
{
Sys_FreeModule(m_pLibrary);
}
m_pLibrary = NULL;
CreateInterface = NULL;
m_szName = NULL;
}
IBaseInterface* GetInterface(const char* pName, int* pReturnCode) const
{
if (CreateInterface)
return (IBaseInterface*)CreateInterface(pName, pReturnCode);
return NULL;
}
void* Resolve(const char* name) const
{
#ifdef POSIX
void* ret = dlsym(m_pLibrary, name);
#else
void* ret = GetProcAddress((HMODULE)m_pLibrary, name);
#endif
if (!ret)
{
#ifdef POSIX
LogPrintf("Module::Resolve: Failed to resolve %s from %s: %s\n", name, m_szName, dlerror());
#else
LogPrintf("Module::Resolve: Failed to resolve %s from %s: %d\n", name, m_szName, GetLastError());
#endif
}
return ret;
}
const char* Name(void) const
{
return m_szName;
}
const void* GetHandle(void) const
{
return m_pLibrary;
}
private:
const char* m_szName;
HINTERFACEMODULE m_pLibrary;
void* (*CreateInterface)(const char* pName, int* pReturnCode);
};
struct Loader
{
Loader(void);
~Loader(void);
void LoadAllLibraries(void);
struct LoaderPrivate* p;
};
extern struct Loader g_Loader;
typedef void (*WrapInitFn)(Module* module);
// Used to wrap classes.
struct WrapInterfaceReg
{
WrapInterfaceReg(const char* pModuleName, const char* pName, IBaseInterface** iface, WrapInitFn fn = NULL, WrapInitFn fnDestruct = NULL);
WrapInterfaceReg(const char* pModuleName, bool isModule = true, WrapInitFn fn = NULL, WrapInitFn fnDestruct = NULL);
~WrapInterfaceReg();
IBaseInterface** m_pIface;
const char* m_szModuleName;
const char* m_szName;
bool m_bIsModule;
WrapInitFn m_pfn;
WrapInitFn m_pfnDestruct;
WrapInterfaceReg* m_pNext; // For the global list.
static WrapInterfaceReg* s_pInterfaceRegs;
};
#define VA_ARGS(...) , ##__VA_ARGS__
#define GET_INTERFACE_PTR(szReadableName, pModule, pName, iface, ...) \
static WrapInterfaceReg __g_Wrap##szReadableName##_reg((pModule), (pName), (IBaseInterface**)(iface) VA_ARGS(__VA_ARGS__) )
#define WRAP_LIBRARY( szReadableName, pModule, ... ) static WrapInterfaceReg __g_Wrap##szReadableName##_reg(pModule, false VA_ARGS(__VA_ARGS__) )
#define WRAP_MODULE( szReadableName, pModule, ... ) static WrapInterfaceReg __g_Wrap##szReadableName##_reg(pModule, true VA_ARGS(__VA_ARGS__) )