Index: /trunk/src/VBox/Main/cbinding/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/cbinding/Makefile.kmk	(revision 16831)
+++ /trunk/src/VBox/Main/cbinding/Makefile.kmk	(revision 16832)
@@ -62,4 +62,13 @@
  	VBoxXPCOMC.cpp
 
+ #
+ # The C glue library.
+ #
+ LIBRARIES.linux += VBoxXPCOMCGlue
+ VBoxXPCOMCGlue_TEMPLATE = VBOXMAINEXE
+ VBoxXPCOMCGlue_DEFS = MOZ_UNICODE IN_VBOXXPCOMC
+ VBoxXPCOMCGlue_SOURCES = \
+ 	VBoxXPCOMCGlue.c
+
  ifdef VBOX_WITH_TESTCASES
   #
Index: /trunk/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
===================================================================
--- /trunk/src/VBox/Main/cbinding/VBoxXPCOMC.cpp	(revision 16831)
+++ /trunk/src/VBox/Main/cbinding/VBoxXPCOMC.cpp	(revision 16832)
@@ -154,3 +154,35 @@
 }
 
+
+VBOXXPCOMC_DECL(PCVBOXXPCOM)
+VBoxGetXPCOMCFunctions(unsigned uVersion)
+{
+    /* The current version. */
+    static const VBOXXPCOMC s_Functions =
+    {
+        sizeof(VBOXXPCOMC),
+        VBOX_XPCOMC_VERSION,
+
+        VBoxComInitialize,
+        VBoxComUninitialize,
+
+        VBoxComUnallocMem,
+        VBoxUtf16Free,
+        VBoxUtf8Free,
+
+        VBoxUtf16ToUtf8,
+        VBoxUtf8ToUtf16,
+
+        VBoxGetEnv,
+        VBoxSetEnv,
+
+        VBOX_XPCOMC_VERSION
+    };
+
+    if ((uVersion & 0xffff0000U) != VBOX_XPCOMC_VERSION)
+        return NULL; /* not supported. */
+
+    return &s_Functions;
+}
+
 /* vim: set ts=4 sw=4 et: */
Index: /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c
===================================================================
--- /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c	(revision 16832)
+++ /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c	(revision 16832)
@@ -0,0 +1,187 @@
+/* $Revsion: $ */
+/** @file
+ * Glue code for dynamically linking to VBoxXPCOMC.
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "VBoxXPCOMCGlue.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#if defined(__linux__) || defined(__linux_gnu__) || defined(__sun__)
+# define DYNLIB_NAME    "VBoxXPCOMC.so"
+#elif defined(__APPLE__)
+# define DYNLIB_NAME    "VBoxXPCOMC.dylib"
+#elif defined(_MSC_VER) || defined(__OS2__)
+# define DYNLIB_NAME    "VBoxXPCOMC.dll"
+#else
+# error "Port me"
+#endif
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+/** The dlopen handle for VBoxXPCOMC. */
+void *g_hVBoxXPCOMC = NULL;
+/** The last load error. */
+char g_szVBoxXPCOMErrMsg[256];
+/** Pointer to the VBoxXPCOMC function table.  */
+PCVBOXXPCOM g_pVBoxFuncs = NULL;
+
+
+/**
+ * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all
+ * the symbols we need.
+ *
+ * @returns 0 on success, -1 on failure.
+ * @param   pszHome         The director where to try load VBoxXPCOMC from. Can be NULL.
+ * @param   pszMsgPrefix    Error message prefix. NULL means no error messages.
+ */
+static int tryLoadOne(const char *pszHome, const char *pszMsgPrefix)
+{
+    size_t      cchHome = pszHome ? strlen(pszHome) : 0;
+    size_t      cbBuf;
+    char *      pszBuf;
+    int         rc = -1;
+
+    /*
+     * Construct the full name.
+     */
+    cbBuf = cchHome + sizeof("/" DYNLIB_NAME);
+    pszBuf = (char *)malloc(cbBuf);
+    if (!pszBuf)
+    {
+        sprintf(g_szVBoxXPCOMErrMsg, "malloc(%u) failed", (unsigned)cbBuf);
+        if (pszMsgPrefix)
+            fprintf(stderr, "%s%s\n", pszMsgPrefix, g_szVBoxXPCOMErrMsg);
+        return -1;
+    }
+    if (pszHome)
+    {
+        memcpy(pszBuf, pszHome, cchHome);
+        pszBuf[cchHome] = '/';
+        cchHome++;
+    }
+    memcpy(&pszBuf[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME));
+
+    /*
+     * Try load it by that name, setting the VBOX_APP_HOME first (for now).
+     * Then resolve and call the function table getter.
+     */
+    setenv("VBOX_APP_HOME", pszHome, 0 /* no need to overwrite */);
+    g_hVBoxXPCOMC = dlopen(pszBuf, RTLD_NOW | RTLD_LOCAL);
+    if (g_hVBoxXPCOMC)
+    {
+        PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions;
+        pfnGetFunctions = (PFNVBOXGETXPCOMCFUNCTIONS)
+            dlsym(g_hVBoxXPCOMC, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME);
+        if (pfnGetFunctions)
+        {
+            g_pVBoxFuncs = pfnGetFunctions(VBOX_XPCOMC_VERSION);
+            if (g_pVBoxFuncs)
+                rc = 0;
+            else
+                sprintf(g_szVBoxXPCOMErrMsg, "%.80s: pfnGetFunctions(%#x) failed",
+                        pszBuf, VBOX_XPCOMC_VERSION);
+        }
+        else
+            sprintf(g_szVBoxXPCOMErrMsg, "dlsym(%.80s/%.32s): %128s",
+                    pszBuf, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, dlerror());
+    }
+    else
+        sprintf(g_szVBoxXPCOMErrMsg, "dlopen(%.80s): %128s", pszBuf, dlerror());
+    free(pszBuf);
+    return rc;
+}
+
+
+/**
+ * Tries to locate and load VBoxXPCOMC.so/dylib/dll, resolving all the related
+ * function pointers.
+ *
+ * @returns 0 on success, -1 on failure.
+ * @param   pszMsgPrefix    Error message prefix. NULL means no error messages.
+ *
+ * @remark  This should be considered moved into a separate glue library since
+ *          its its going to be pretty much the same for any user of VBoxXPCOMC
+ *          and it will just cause trouble to have duplicate versions of this
+ *          source code all around the place.
+ */
+int VBoxCGlueInit(const char *pszMsgPrefix)
+{
+    /*
+     * If the user specifies the location, try only that.
+     */
+
+    const char *pszHome = getenv("VBOX_APP_HOME");
+    if (pszHome)
+        return tryLoadOne(pszHome, pszMsgPrefix);
+
+    /*
+     * Try the known standard locations.
+     */
+
+#if defined(__gnu__linux__) || defined(__linux__)
+    if (tryLoadOne("/opt/VirtualBox", pszMsgPrefix) == 0)
+        return 0;
+    if (tryLoadOne("/usr/lib/virtualbox", pszMsgPrefix) == 0)
+        return 0;
+#elif defined(__sun__)
+    if (tryLoadOne("/opt/VirtualBox/amd64", pszMsgPrefix) == 0)
+        return 0;
+    if (tryLoadOne("/opt/VirtualBox/i386", pszMsgPrefix) == 0)
+        return 0;
+#elif defined(__APPLE__)
+    if (tryLoadOne("/Application/VirtualBox.app/Contents/MacOS", pszMsgPrefix) == 0)
+        return 0;
+#else
+# error "port me"
+#endif
+
+    /*
+     * Finally try the dynamic linker search path.
+     */
+
+    if (tryLoadOne(NULL, pszMsgPrefix) == 0)
+        return 0;
+
+    /* No luck, return failure. */
+    if (pszMsgPrefix)
+        fprintf(stderr, "%sFailed to locate VBoxXPCOMC\n", pszMsgPrefix);
+    return -1;
+}
+
+
+/**
+ * Terminate the C glue library.
+ */
+void VBoxCGlueTerm(void)
+{
+    /* later */
+}
+
Index: /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
===================================================================
--- /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h	(revision 16832)
+++ /trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h	(revision 16832)
@@ -0,0 +1,47 @@
+/* $Revision$ */
+/** @file cbinding.h
+ * Glue for dynamically linking with VBoxXPCOMC.
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef ___VBoxXPCOMC_cglue_h
+#define ___VBoxXPCOMC_cglue_h
+
+#include "cbinding.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The dlopen handle for VBoxXPCOMC. */
+extern void *g_hVBoxXPCOMC;
+/** The last load error. */
+extern char g_szVBoxXPCOMErrMsg[256];
+/** Pointer to the VBoxXPCOMC function table.  */
+extern PCVBOXXPCOM g_pVBoxFuncs;
+
+int VBoxCGlueInit(const char *pszMsgPrefix);
+void VBoxCGlueTerm(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /trunk/src/VBox/Main/cbinding/cbinding.h
===================================================================
--- /trunk/src/VBox/Main/cbinding/cbinding.h	(revision 16831)
+++ /trunk/src/VBox/Main/cbinding/cbinding.h	(revision 16832)
@@ -56,4 +56,50 @@
 VBOXXPCOMC_DECL(int) VBoxSetEnv(const char *pszVar, const char *pszValue);
 
+
+/**
+ * Function table for dynamic linking.
+ * Use VBoxGetFunctions() to obtain the pointer to it.
+ */
+typedef struct VBOXXPCOMC
+{
+    /** The size of the structure. */
+    unsigned cb;
+    /** The structure version. */
+    unsigned uVersion;
+    void  (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
+    void  (*pfnComUninitialize)(void);
+
+    void  (*pfnComUnallocMem)(void *pv);
+    void  (*pfnUtf16Free)(PRUnichar *pwszString);
+    void  (*pfnUtf8Free)(char *pszString);
+
+    int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
+    int   (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
+
+    const char * (*pfnGetEnv)(const char *pszVar);
+    int   (*pfnSetEnv)(const char *pszVar, const char *pszValue);
+    /** Tail version, same as uVersion. */
+    unsigned uEndVersion;
+} VBOXXPCOMC;
+/** Pointer to a const VBoxXPCOMC function table. */
+typedef VBOXXPCOMC const *PCVBOXXPCOM;
+
+/** The current interface version.
+ * For use with VBoxGetXPCOMCFunctions and to be found in
+ * VBOXXPCOMC::uVersion. */
+#define VBOX_XPCOMC_VERSION     0x00010000U
+
+VBOXXPCOMC_DECL(PCVBOXXPCOM) VBoxGetXPCOMCFunctions(unsigned uVersion);
+/** Typedef for VBoxGetXPCOMCFunctions. */
+typedef PCVBOXXPCOM (*PFNVBOXGETXPCOMCFUNCTIONS)(unsigned uVersion);
+
+/** The symbol name of VBoxGetXPCOMCFunctions. */
+#if defined(__APPLE__) || defined(__OS2__)
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME   "_VBoxGetXPCOMCFunctions"
+#else
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME   "VBoxGetXPCOMCFunctions"
+#endif
+
+
 #ifdef __cplusplus
 }
