X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/80fdcdb90ef779185492dab676d461fc34933312..739c5499fcab1c165b8dd0591c9fd9e2329b3cf9:/src/msw/dlmsw.cpp

diff --git a/src/msw/dlmsw.cpp b/src/msw/dlmsw.cpp
index cdff7387ab..0bb76d72db 100644
--- a/src/msw/dlmsw.cpp
+++ b/src/msw/dlmsw.cpp
@@ -27,6 +27,7 @@
 
 #include "wx/msw/private.h"
 #include "wx/msw/debughlp.h"
+#include "wx/filename.h"
 
 const wxString wxDynamicLibrary::ms_dllext(wxT(".dll"));
 
@@ -224,13 +225,62 @@ wxDllType wxDynamicLibrary::GetProgramHandle()
 // loading/unloading DLLs
 // ----------------------------------------------------------------------------
 
+#ifndef MAX_PATH
+    #define MAX_PATH 260        // from VC++ headers
+#endif
+
 /* static */
 wxDllType
 wxDynamicLibrary::RawLoad(const wxString& libname, int flags)
 {
-    return flags & wxDL_GET_LOADED
-            ? ::GetModuleHandle(libname.t_str())
-            : ::LoadLibrary(libname.t_str());
+    if (flags & wxDL_GET_LOADED)
+        return ::GetModuleHandle(libname.t_str());
+
+    // Explicitly look in the same path as where the main wx HINSTANCE module
+    // is located (usually the executable or the DLL that uses wx).  Normally
+    // this is automatically part of the default search path but in some cases
+    // it may not be, such as when the wxPython extension modules need to load
+    // a DLL, but the intperpreter executable is located elsewhere.  Doing
+    // this allows us to always be able to dynamically load a DLL that is
+    // located at the same place as the wx modules.
+    wxString modpath, path;
+    ::GetModuleFileName(wxGetInstance(),
+                        wxStringBuffer(modpath, MAX_PATH+1),
+                        MAX_PATH);
+    
+    wxFileName::SplitPath(modpath, &path, NULL, NULL);
+
+    typedef BOOL (WINAPI *SetDllDirectory_t)(LPCTSTR lpPathName);
+
+    static SetDllDirectory_t s_pfnSetDllDirectory = (SetDllDirectory_t) -1;
+
+    if ( s_pfnSetDllDirectory == (SetDllDirectory_t) -1 )
+    {
+        /*
+        Should wxLoadedDLL ever not be used here (or rather, the
+        wxDL_GET_LOADED flag isn't used), infinite recursion will take
+        place (unless s_pfnSetDllDirectory is set to NULL here right
+        before loading the DLL).
+        */
+        wxLoadedDLL dllKernel("kernel32.dll");
+
+        wxDL_INIT_FUNC_AW(s_pfn, SetDllDirectory, dllKernel);
+    }
+
+    if (s_pfnSetDllDirectory)
+    {
+        s_pfnSetDllDirectory(path.t_str());
+    }
+
+    wxDllType handle = ::LoadLibrary(libname.t_str());
+
+    // reset the search path
+    if (s_pfnSetDllDirectory)
+    {
+        s_pfnSetDllDirectory(NULL);
+    }
+
+    return handle;
 }
 
 /* static */