Debug DLL loading issue from Java (error 127) due to different Intel Fortran Compiler (Classic) versions

Hi all,

I am trying to get a DLL created with Fortran to load into some Java program via a wrapper class as follows (the Java program is external, I do not develop this myself):

//
// IMPLEMENTATION OF EXPORTED FUNCTIONS
//
JNIEXPORT jboolean JNICALL Foo1_InitializeW (JNIEnv *env, jobject, jboolean j_debug)
{	
	myDebug = j_debug;
	if (myDebug) cout << "\nCPP:initializeW: initializing wrapper 1.1...\n";
	cleanup();

	// get handle to Fortran DLL:
	DWORD errorCode = -1;
	FortranDll_H = LoadLibrary(L"Dll_Fortran.dll");
	errorCode= GetLastError();

...
}

That last line returns the error code 127. Apparently something goes wrong when loading the DLL. However, the DLL loads fine when compiled on different machines with an older version of the intel ifort (“classic”) compiler (both with the same and an older version of Microsoft Visual Studio). The DLL is compiled for a Win32 platform. It uses some external 32-bit libraries via linking of .lib files.

This is a slightly cleaned up BuildLog (this works):

Build Log
 	 	
 Build started: Project: Dll_Fortran, Configuration: Debug|Win32 
Output
 	 	
Deleting intermediate files and output files for project 'Dll_Fortran', configuration 'Debug|Win32'.
Compiling with Intel(R) Visual Fortran Compiler 19.1.3.311 [IA-32]...
ifort /nologo /debug:full /Od /I"..\LIBPATH1" /I"..\PATH1\modules" /extend_source:80 /warn:interfaces /fpe:0 /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc140.pdb" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86" /Qm32 "C:\...\LIB2.for"
ifort /nologo /debug:full /Od /I"..\LIBPATH1" /I"..\PATH1\modules" /extend_source:80 /warn:interfaces /fpe:0 /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc140.pdb" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86" /Qm32 "C:\...\LIB2Interface.for"
ifort /nologo /debug:full /Od /I"..\LIBPATH1" /I"..\PATH1\modules" /extend_source:80 /warn:interfaces /fpe:0 /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc140.pdb" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86" /Qm32 "C:\...\Calcs.for"
ifort /nologo /debug:full /Od /I"..\LIBPATH1" /I"..\PATH1\modules" /extend_source:80 /warn:interfaces /fpe:0 /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc140.pdb" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX86\x86" /Qm32 "C:\...\Dll_Fortran.f90"
Linking...
Link /OUT:"Debug/DLL_Fortran.dll" /INCREMENTAL:NO /NOLOGO /NODEFAULTLIB:"MSVCRT" /MANIFEST:NO /DEBUG /PDB:"Debug/DLL_Fortran.pdb" /SUBSYSTEM:WINDOWS /IMPLIB:"C:\...\Debug\DLL_Fortran.lib" /DLL ..\LIBPATH1\LIB1-1.lib ..\LIBPATH1\LIB1-2.LIB ..\LIBPATH1\LIB1-3.LIB ..\LIBPATH1\LIB1-4.lib ..\LIBPATH2\LIB2.lib -qm32 "Debug\LIB2.obj" "Debug\LIB2Interface.obj" "Debug\Calcs.obj" "Debug\Dll_Fortran.obj"
   Creating library C:\...\Debug\Dll_Fortran.lib and object C:\...\Debug\Dll_Fortran.exp

Dll_Fortran - 0 error(s), 0 warning(s)

It works with the following compiler version:

Intel(R) Visual Fortran Compiler 19.1.3.311 [IA-32]

It does not work with the newer compiler version (BuildLog looks the same otherwise):

Intel® Fortran Compiler Classic 2021.10.0 [IA-32]

What could be the reason for this?

Does the newer compiler cause an issue with the libraries that I use for the DLL? However, I can compile the program as an executable with the libraries and run it just fine with the newer compiler.

Did perhaps some default settings of the compiler change in the meantime? How can I go about debugging this possibility?

Is there any other approach I could follow?

I have dumpbin available in MS Visual studio, but do not exactly know where to look. dumpbin /EXPORTS Dll_Fortran.dll gives identical output for DLLs created with both compilers, apart from the memory addresses (?) in the column RVA.

Any advice would be very welcome. :slight_smile:

Thanks,
Marcus

1 Like

Update for everyone who may have a similar problem: The issue seems to be related to other libraries, that are used by the DLL loaded into Java. When compiling the Fortran-DLL, a switch to the compiler directive

/libs:static

from formerly /libs:dll seems to circumvent the problem - via this setting in MS Visual Studio 2019:

It is still not clear to me, why a change in the compiler version would cause this issue.

Can this be somehow related to the calling conventions in the DLL dependencies? For instance, one the two DLL uses interface definitions of the form

            SUBROUTINE EXAMPLE(INDEX1,INDEX2)
              INTEGER(KIND=4) :: INDEX1
              INTEGER(KIND=4) :: INDEX2(*)
            !DEC$ ATTRIBUTES CVF :: EXAMPLE
            END SUBROUTINE EXAMPLE

where !DEC$ ATTRIBUTES CVF is required by the supplier of the DLL to enforce the calling convention compatible with Compaq Visual Fortran.

The problem is less urgent now, but nevertheless any insight would be appreciated.

1 Like

Ok, we could solve the problem, so for posterity:

The issue was some apparently changed DLL of the Intel Fortran (Classic) Compiler runtime environment, similar to how it is described in this thread:
community.intel.com

The runtime DLLs needed to be updated on the machine where the DLL was loaded into the Java programme.

The other external libraries above were innocent. The offending libraries could be identified using dumpbin /DEPENDENTS EXAMPLE.DLL and comparing the output on the working/non-working DLL versions (with static/dynamic linking). Dumpbin is available from PowerShell within MS Visual Studio.

The Intel Fortran compiler runtime can be downloaded here or the required DLLs can be located in a folder named similarly (here e.g. for 32-bit and version 2020.4.311) on Windows:
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.4.311\windows\redist\ia32_win\compiler

1 Like

I use Dependency Walker (the new version) for this sort of things - GitHub - lucasg/Dependencies: A rewrite of the old legacy software "depends.exe" in C# for Windows devs to troubleshoot dll load dependencies issues.. It is a very useful tool, though the DLLs that are reported are sometimes surprising - in location and in name. You have to get to know your way around a bit.

dumpbin is presumably doing something similar, I simply do not know it well enough :innocent:.

1 Like