[gedit] W32: load libgedit.dll at runtime



commit b2aa4553ef0b6df9faaa8a9a98fed1607fc0f3aa
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date:   Sat Apr 5 12:53:03 2014 +0000

    W32: load libgedit.dll at runtime
    
    Since libgedit is linked as delay-loaded DLL, it's still not loaded when
    main() is called. Before we call functions from it, we must locate
    libgedit.dll and load it (otherwise, if it's not in PATH (which is how it
    should be!), calling its functions will crash the program).
    As comments indicate, the use of g_module_open() is not really necessary,
    but, given the circumstances, it is convenient and clean.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=727663

 gedit/gedit.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 1 deletions(-)
---
diff --git a/gedit/gedit.c b/gedit/gedit.c
index 3939fb5..c55eec1 100644
--- a/gedit/gedit.c
+++ b/gedit/gedit.c
@@ -33,6 +33,62 @@
 #endif
 #endif
 
+#ifdef G_OS_WIN32
+#include <gmodule.h>
+static GModule *libgedit_dll = NULL;
+
+/* This code must live in gedit.exe, not in libgedit.dll, since the whole
+ * point is to find and load libgedit.dll.
+ */
+static void
+gedit_w32_load_private_dll (GType *type)
+{
+       gchar *dllpath;
+       gchar *prefix;
+
+       prefix = g_win32_get_package_installation_directory_of_module (NULL);
+
+       if (prefix != NULL)
+       {
+               /* Instead of g_module_open () it may be possible to do any of the
+                * following:
+                * A) Change PATH to "${dllpath}/lib/gedit;$PATH"
+                * B) Call SetDllDirectory ("${dllpath}/lib/gedit")
+                * C) Call AddDllDirectory ("${dllpath}/lib/gedit")
+                * But since we only have one library, and its name is known, may as well
+                * use gmodule.
+                */
+               dllpath = g_build_filename (prefix, "lib", "gedit", "libgedit.dll", NULL);
+               g_free (prefix);
+               libgedit_dll = g_module_open (dllpath, 0);
+               g_free (dllpath);
+       }
+
+       if (libgedit_dll == NULL)
+       {
+               libgedit_dll = g_module_open ("libgedit.dll", 0);
+       }
+
+       if (libgedit_dll != NULL)
+       {
+               /* Now that we did everything we could to make the DLL available, we can
+                * implicitly call the *_get_type() function from it.
+                */
+               *type = GEDIT_TYPE_APP_WIN32;
+       }
+}
+
+static void
+gedit_w32_unload_private_dll ()
+{
+       if (libgedit_dll)
+       {
+               g_module_close (libgedit_dll);
+               libgedit_dll = NULL;
+       }
+}
+#endif
+
 int
 main (int argc, char *argv[])
 {
@@ -44,7 +100,7 @@ main (int argc, char *argv[])
        type = GEDIT_TYPE_APP_OSX;
 #else
 #ifdef G_OS_WIN32
-       type = GEDIT_TYPE_APP_WIN32;
+       gedit_w32_load_private_dll (&type);
 #else
        type = GEDIT_TYPE_APP_X11;
 #endif
@@ -59,6 +115,10 @@ main (int argc, char *argv[])
 
        g_object_unref (app);
 
+#ifdef G_OS_WIN32
+       gedit_w32_unload_private_dll ();
+#endif
+
        return status;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]