0

I am working on the development of a Java application that loads native library files to perform some calculations. The application uses JNI to load the libraries. This application should work on Windows and Linux environments (on both 32-bit and 64-bit).

During the compilation process, we compile C code to library files (32-bit and 64-bit dlls for Windows, and 32-bit and 64-bit .so files for Linux environments). These .dlls and .so files are included in the distribution file, and are referenced when Java is called by using the -Djava.library.path parameter.

I am now testing the application on a few different machines. I am initially focused on 64-bit Windows environments. The strange thing that I have encountered is that on some 64-bit machines the application loads the correct .dll files successfully, but on some other machines it does not load the .dlls.

I thought that the problem might because of a difference in the processor type between the machines (ie. that the dlls were compiled for one processor type and other processors types cannot use them).

However, it works on one machine, and does not work on another machine that has the SAME processor:

It works on a HP laptop running Windows 7 64-bit, with this processor:

PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 37 Stepping 5, GenuineIntel

It does not work on a Lenovo laptop running Window 7 64-bit, with this processor:

PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel

My question is: apart from the bitness are .dlls machine/processor type specific in some other way? (I know that the .dll files have to match the bitness of the machine, and that the JVM must also match the bitness of the .dll files)

Or in theory, if a .dll is 64-bit should it run on EVERY 64-bit machine that is using a 64-bit JVM?

user3441604
  • 582
  • 7
  • 23
  • I'm confused. 64-bit JVM used to compile C files to 64-bit dll? While Andrew is right in principle, just instruct your C compiler to generate code for the lowest CPU you support (or all x86_64 CPUs) and avoid OS calls introduced after the lowest version of Windows you support. – Marco van de Voort Dec 18 '15 at 13:47

1 Answers1

1

apart from the bitness are .dlls machine/processor type specific in some other way?

Very much so. Any compiled binary meant to run under an operating system is both processor and operating system specific, sometimes even down to specific versions of each.

Different processors - even in the same family, such as "x86" - can offer different instruction sets and capabilities. See https://en.wikipedia.org/wiki/X86_instruction_listings for the listing of different variations of just x86 instruction sets and capabilities. If a compiled binary uses a specific instruction, it won't run on a processor that doesn't implement that instruction. For example, if a binary is compiled to use SSE3 instructions, it won't run on processors that don't implement SSE3.

And it's not just limited to hardware, either. Operating system specifics matter, too, literally for starters because the operating system is what starts the running process. So the binary needs to work under the conditions and in the environment of the operating system that started it. A binary designed to work under an operating system will also need to make calls to that operating system to interact with data, devices, or other processes. Different operating systems provide these capabilities in vastly different ways, even to the point of different versions of the same basic operating system doing so in incompatible ways.

And binaries that aren't designed to run under an operating system have to provide very hardware-specific capabilities - ever notice how many device drivers any operating system has? And this excludes any shared object or DLL because by definition they are already designed to run under an operating system.

Or in theory, if a .dll is 64-bit should it run on EVERY 64-bit machine that is using a 64-bit JVM?

It should be clear by now that the answer is "Not even close".

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Hi, thanks for that answer. Your answer confirms what I thought. I guess the best that we can do is generate dlls for the most commonly encountered processors. But its not clear to me how to identify the different processors. For example, in the case of the two laptops that I mentioned in the question, both suggest that they have the same processor, but obviously there is a difference between them. One extra piece of information, i think that all the machines which fail to load the precompiled dlls have the sticker "intel Core i5". – user3441604 Dec 18 '15 at 11:18
  • continuing my previous comment: we could generate a dll using an "Intel core i5" processor (which seems to be one processor that is not able to use the existing dlls), but what other dlls should be included in the distribution? Note: the distribution also include the source code, which allows the end-user to compile a dll themselves, but that puts a lot of responsibility on the end-user. – user3441604 Dec 18 '15 at 11:32
  • Your best bet, unless you're doing performance-critical processing, is to generate all your libraries for "lowest common denominator" CPU architectures. Things might run a bit slower, but they'll run. For GCC, the `-march` flag could be set to something like `core2` (see https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/i386-and-x86_002d64-Options.html), and for MS compilers see http://stackoverflow.com/questions/23259531/what-is-the-minimum-target-cpu-architecture-for-the-various-versions-of-visual-s That's a lot easier than trying to provide architecture-specific libraries. – Andrew Henle Dec 18 '15 at 11:39