changeset 22146:ef91e43f162a

set DLL directory when loading DLLs on Windows systems (bug #48511) * file-ops.h (file_ops::dirname): New function. * oct-shlib.cc (set_dll_directory): New function. (octave_w32_shlib::octave_w32_shlib): Call file_ops::dirname to get directory part of shared library file, then use set_dll_directory to temporarily alter DLL search path. * ov-java.cc (set_dll_directory): Delete. (initialize_jvm): Don't set DLL search path for Windows systems here. That job is now handled by octave::dynamic_library.
author John W. Eaton <jwe@octave.org>
date Tue, 19 Jul 2016 12:07:34 -0400
parents cf5145769e37
children da413c03920c
files libinterp/octave-value/ov-java.cc liboctave/system/file-ops.h liboctave/util/oct-shlib.cc
diffstat 3 files changed, 23 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-java.cc	Tue Jul 19 11:29:29 2016 -0400
+++ b/libinterp/octave-value/ov-java.cc	Tue Jul 19 12:07:34 2016 -0400
@@ -330,26 +330,6 @@
   return (found ? retval : "");
 }
 
-static void
-set_dll_directory (const std::string& dir = "")
-{
-  typedef BOOL (WINAPI *dllfcn_t) (LPCTSTR path);
-
-  static dllfcn_t dllfcn = 0;
-  static bool first = true;
-
-  if (! dllfcn && first)
-    {
-      HINSTANCE hKernel32 = GetModuleHandle ("kernel32");
-      dllfcn = reinterpret_cast<dllfcn_t> (GetProcAddress (hKernel32,
-                                           "SetDllDirectoryA"));
-      first = false;
-    }
-
-  if (dllfcn)
-    dllfcn (dir.empty () ? 0 : dir.c_str ());
-}
-
 #endif
 
 static std::string
@@ -519,7 +499,6 @@
 
   HMODULE hMod = GetModuleHandle ("jvm.dll");
   std::string jvm_lib_path;
-  std::string old_cwd;
 
   if (hMod)
     {
@@ -558,20 +537,6 @@
       if (jvm_lib_path.empty ())
         error ("unable to find Java Runtime Environment: %s::%s",
                key.c_str (), value.c_str ());
-
-      std::string jvm_bin_path;
-
-      value = "JavaHome";
-      jvm_bin_path = read_registry_string (key, value);
-      if (! jvm_bin_path.empty ())
-        {
-          jvm_bin_path = (jvm_bin_path + std::string ("\\bin"));
-
-          old_cwd = octave::sys::env::get_current_directory ();
-
-          set_dll_directory (jvm_bin_path);
-          octave::sys::env::chdir (jvm_bin_path);
-        }
     }
 
 #else
@@ -595,15 +560,6 @@
     error ("unable to load Java Runtime Environment from %s",
            jvm_lib_path.c_str ());
 
-#if defined (OCTAVE_USE_WINDOWS_API)
-
-  set_dll_directory ();
-
-  if (! old_cwd.empty ())
-    octave::sys::env::chdir (old_cwd);
-
-#endif
-
   JNI_CreateJavaVM_t create_vm =
     reinterpret_cast<JNI_CreateJavaVM_t> (lib.search ("JNI_CreateJavaVM"));
   JNI_GetCreatedJavaVMs_t get_vm =
--- a/liboctave/system/file-ops.h	Tue Jul 19 11:29:29 2016 -0400
+++ b/liboctave/system/file-ops.h	Tue Jul 19 12:07:34 2016 -0400
@@ -99,6 +99,16 @@
 
       static std::string concat (const std::string&, const std::string&);
 
+      // Return the directory part of a filename or an empty string if
+      // there is no directory component.  Does not check to see
+      // whether the file exists or is a directory.
+      static std::string dirname (const std::string& path)
+      {
+        size_t ipos = path.find_last_of (dir_sep_chars ());
+
+        return (ipos != std::string::npos) ? path.substr (0, ipos) : "";
+      }
+      
       // Return the tail member of a filename.
       static std::string tail (const std::string& path)
       {
--- a/liboctave/util/oct-shlib.cc	Tue Jul 19 11:29:29 2016 -0400
+++ b/liboctave/util/oct-shlib.cc	Tue Jul 19 12:07:34 2016 -0400
@@ -55,6 +55,7 @@
 #endif
 }
 
+#include "file-ops.h"
 #include "file-stat.h"
 #include "lo-error.h"
 #include "oct-shlib.h"
@@ -339,11 +340,23 @@
     HINSTANCE handle;
   };
 
+  static void
+  set_dll_directory (const std::string& dir = "")
+  {
+    SetDllDirectory (dir.empty () ? 0 : dir.c_str ());
+  }
+
   octave_w32_shlib::octave_w32_shlib (const std::string& f)
     : dynamic_library::dynlib_rep (f), handle (0)
   {
+    std::string dir = octave::sys::file_ops::dirname (f);
+
+    set_dll_directory (dir);
+
     handle = LoadLibrary (file.c_str ());
 
+    set_dll_directory ();
+    
     if (! handle)
       {
         DWORD lastError = GetLastError ();