Nic Bolton
Nic Bolton

Reputation: 3

DLL only loads when MinGW path is set

I have been working on a plug-in for ImageJ to use. What the program does is irrelevant (I think), but it is written mainly in Java and calls to C++ using JNI.

I compile the program using the following:

javac MyProgram.java OtherClass.java OtherOtherClass.java -cp ij.jar

javah -cp . MyProgram

g++ -c -I"%JAVA_HOME%/include" -I"%JAVA_HOME%/include/win32" -m64 -fPIC MyProgram.cpp -o MyProgram.o

g++ -shared -m64 -o MyProgram_Native.dll MyProgram.o -Wl,-add-stdcall-alis

And this gives me my .class, .o, and .dll files that I need. So my DLL that gets made, MyProgram_Native.dll, is the center of the problem.

The computer that I have been building this program on can execute the plug-in just fine. It can do all the stuff we need it to do, and it works great.

So I shipped it off to my other co-workers for them to try, but it wouldn't work for them. I gave them the three .class files along with the .o file and the .dll file. ImageJ (the program for the plug-in) handles the plug-ins by having the files I gave to my co-workers placed into a subfolder in ImageJ's plug-in folder.

So we have ImageJ>plug-ins>MYPLUGIN>*.

Every time the program doesn't work, I see the error message in the log file: "java.lang.UnsatisfiedLinkError C:/.../: Can't find dependent libraries.

But today I figured out that whenever I have my MinGW folder set in my PATH variable, the program finds the DLL and it works fine. But when I remove MinGW from the PATH variable the program cannot find the DLL and the plug-in doesn't work and gives the error message above.

My MinGW path is set to C:\msys64\mingw64\bin

I am getting the .dll in Java using:

  private static final String DLL_PATH = System.getProperty("user.dir") + 
  "\\plugins\\MyPlugin\\MyProgram_Native.dll";

  // needed to call JNI
  static {
    logger = new LogManager();
    logger.addInfo("Attempting to load .dll");

    try {
      logger.addVariable("DLL_PATH", DLL_PATH);
      System.load(DLL_PATH);
      logger.addInfo(".dll loaded successfully");
    } catch (Throwable exc) {
      logger.addInfo(".dll loading error message:", exc.toString());
    }
  }

So when the MinGW path is set, I get the message ".dll loaded successfully" and the program works. I don't even have to recompile, if I literally close the program, remove the PATH, and try executing the plug-in again, I get the error message above.

I have no idea why this happens. I tried searching online but answers weren't very specific. I would write what I have tried but I don't even know the correlation between MinGW and finding the DLL.

TLDR: Program finds DLL only when MinGW is on PATH variable

Any help would be appreciated. I'm pretty in the dark on this.

I should note that we are using Java 8 on a Windows 10 machine. If I forgot to include any relevant info please let me know.

Upvotes: 0

Views: 769

Answers (1)

Botje
Botje

Reputation: 30860

You compiled your DLL with GCC. Under windows, this dynamically links some helper libraries that are shipped with MinGW. Quoting from this answer

They provide the runtime and standard library.

  • libwinpthread: PThreads implementation on Windows (Threading)
  • libstdc++: C++ Standard Library (C/C++ library functions etc.)
  • libgcc_s_seh: Exception handling (SEH)

Adding MinGW to PATH will make these DLLs visible to the standard windows DLL loading mechanism. Alternatively, you can simply put these DLL files next to your DLL and Windows will find them as well.

If you do not want that, you have the option of statically linking these libraries. Read up on the -static-libstdc++ and -static-libgcc flags for that, or search this site for more.

Upvotes: 1

Related Questions