VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c@ 49539

最後變更 在這個檔案從49539是 49539,由 vboxsync 提交於 11 年 前

Main/cbinding: lots of love and care for this long forgotten part of the code, make it easier to use and more functional (error handling, initialization), and clean up and extend the sample code. It now includes the event sample, no need to keep so much redundant code.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.8 KB
 
1/* $Revision: 49539 $ */
2/** @file
3 * Glue code for dynamically linking to VBoxXPCOMC.
4 */
5
6/*
7 * Copyright (C) 2008-2013 Oracle Corporation
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <stdarg.h>
38#include <stdint.h>
39#include <dlfcn.h>
40#include <pthread.h>
41
42#include "VBoxXPCOMCGlue.h"
43
44
45/*******************************************************************************
46* Defined Constants And Macros *
47*******************************************************************************/
48#if defined(__linux__) || defined(__linux_gnu__) || defined(__sun__) || defined(__FreeBSD__)
49# define DYNLIB_NAME "VBoxXPCOMC.so"
50#elif defined(__APPLE__)
51# define DYNLIB_NAME "VBoxXPCOMC.dylib"
52#elif defined(_MSC_VER) || defined(__OS2__)
53# define DYNLIB_NAME "VBoxXPCOMC.dll"
54#else
55# error "Port me"
56#endif
57
58
59/*******************************************************************************
60* Global Variables *
61*******************************************************************************/
62/** The dlopen handle for VBoxXPCOMC. */
63void *g_hVBoxXPCOMC = NULL;
64/** The last load error. */
65char g_szVBoxErrMsg[256];
66/** Pointer to the VBoxXPCOMC function table. */
67PCVBOXXPCOM g_pVBoxFuncs = NULL;
68/** Pointer to VBoxGetXPCOMCFunctions for the loaded VBoxXPCOMC so/dylib/dll. */
69PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions = NULL;
70
71typedef void FNDUMMY(void);
72typedef FNDUMMY *PFNDUMMY;
73/** Just a dummy global structure containing a bunch of
74 * function pointers to code which is wanted in the link.
75 * In this case this is for helping gdb as it gets hideously
76 * confused if the application doesn't drag in pthreads.
77 */
78PFNDUMMY g_apfnVBoxXPCOMCGlue[] =
79{
80 (PFNDUMMY)pthread_create
81};
82
83
84/**
85 * Wrapper for setting g_szVBoxErrMsg. Can be an empty stub.
86 *
87 * @param fAlways When 0 the g_szVBoxErrMsg is only set if empty.
88 * @param pszFormat The format string.
89 * @param ... The arguments.
90 */
91static void setErrMsg(int fAlways, const char *pszFormat, ...)
92{
93 if ( fAlways
94 || !g_szVBoxErrMsg[0])
95 {
96 va_list va;
97 va_start(va, pszFormat);
98 vsnprintf(g_szVBoxErrMsg, sizeof(g_szVBoxErrMsg), pszFormat, va);
99 va_end(va);
100 }
101}
102
103
104/**
105 * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all
106 * the symbols we need.
107 *
108 * @returns 0 on success, -1 on failure.
109 * @param pszHome The director where to try load VBoxXPCOMC from. Can
110 * be NULL.
111 * @param fSetAppHome Whether to set the VBOX_APP_HOME env.var. or not
112 * (boolean).
113 */
114static int tryLoadOne(const char *pszHome, int fSetAppHome)
115{
116 size_t cchHome = pszHome ? strlen(pszHome) : 0;
117 size_t cbBufNeeded;
118 char szName[4096];
119 int rc = -1;
120
121 /*
122 * Construct the full name.
123 */
124 cbBufNeeded = cchHome + sizeof("/" DYNLIB_NAME);
125 if (cbBufNeeded > sizeof(szName))
126 {
127 setErrMsg(1, "path buffer too small: %u bytes needed",
128 (unsigned)cbBufNeeded);
129 return -1;
130 }
131 if (cchHome)
132 {
133 memcpy(szName, pszHome, cchHome);
134 szName[cchHome] = '/';
135 cchHome++;
136 }
137 memcpy(&szName[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME));
138
139 /*
140 * Try load it by that name, setting the VBOX_APP_HOME first (for now).
141 * Then resolve and call the function table getter.
142 */
143 if (fSetAppHome)
144 {
145 if (pszHome)
146 setenv("VBOX_APP_HOME", pszHome, 1 /* always override */);
147 else
148 unsetenv("VBOX_APP_HOME");
149 }
150 g_hVBoxXPCOMC = dlopen(szName, RTLD_NOW | RTLD_LOCAL);
151 if (g_hVBoxXPCOMC)
152 {
153 PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions;
154 pfnGetFunctions = (PFNVBOXGETXPCOMCFUNCTIONS)(uintptr_t)
155 dlsym(g_hVBoxXPCOMC, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME);
156 if (pfnGetFunctions)
157 {
158 g_pVBoxFuncs = pfnGetFunctions(VBOX_XPCOMC_VERSION);
159 if (g_pVBoxFuncs)
160 {
161 g_pfnGetFunctions = pfnGetFunctions;
162 return 0;
163 }
164
165 /* bail out */
166 setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
167 szName, VBOX_XPCOMC_VERSION);
168 }
169 else
170 setErrMsg(1, "dlsym(%.80s/%.32s): %.128s",
171 szName, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, dlerror());
172 dlclose(g_hVBoxXPCOMC);
173 g_hVBoxXPCOMC = NULL;
174 }
175 else
176 setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
177 return rc;
178}
179
180
181/**
182 * Tries to locate and load VBoxXPCOMC.so/dylib/dll, resolving all the related
183 * function pointers.
184 *
185 * @returns 0 on success, -1 on failure.
186 *
187 * @remark This should be considered moved into a separate glue library since
188 * its its going to be pretty much the same for any user of VBoxXPCOMC
189 * and it will just cause trouble to have duplicate versions of this
190 * source code all around the place.
191 */
192int VBoxCGlueInit(void)
193{
194 /*
195 * If the user specifies the location, try only that.
196 */
197 const char *pszHome = getenv("VBOX_APP_HOME");
198 if (pszHome)
199 return tryLoadOne(pszHome, 0);
200
201 /*
202 * Try the known standard locations.
203 */
204 g_szVBoxErrMsg[0] = '\0';
205#if defined(__gnu__linux__) || defined(__linux__)
206 if (tryLoadOne("/opt/VirtualBox", 1) == 0)
207 return 0;
208 if (tryLoadOne("/usr/lib/virtualbox", 1) == 0)
209 return 0;
210#elif defined(__sun__)
211 if (tryLoadOne("/opt/VirtualBox/amd64", 1) == 0)
212 return 0;
213 if (tryLoadOne("/opt/VirtualBox/i386", 1) == 0)
214 return 0;
215#elif defined(__APPLE__)
216 if (tryLoadOne("/Application/VirtualBox.app/Contents/MacOS", 1) == 0)
217 return 0;
218#elif defined(__FreeBSD__)
219 if (tryLoadOne("/usr/local/lib/virtualbox", 1) == 0)
220 return 0;
221#elif defined(__OS2__)
222 if (tryLoadOne("C:/Apps/VirtualBox", 1) == 0)
223 return 0;
224#else
225# error "port me"
226#endif
227
228 /*
229 * Finally try the dynamic linker search path.
230 */
231 if (tryLoadOne(NULL, 1) == 0)
232 return 0;
233
234 /* No luck, return failure. */
235 return -1;
236}
237
238
239/**
240 * Terminate the C glue library.
241 */
242void VBoxCGlueTerm(void)
243{
244 if (g_hVBoxXPCOMC)
245 {
246#if 0 /* VBoxRT.so doesn't like being reloaded. See @bugref{3725}. */
247 dlclose(g_hVBoxXPCOMC);
248#endif
249 g_hVBoxXPCOMC = NULL;
250 }
251 g_pVBoxFuncs = NULL;
252 g_pfnGetFunctions = NULL;
253 memset(g_szVBoxErrMsg, 0, sizeof(g_szVBoxErrMsg));
254}
255
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette