I'm trying to write a simple Java program that calls a C function via JNI to print "Hello World". Everything compiles with no errors, but when I run the program I get an "UnsatisfiedLinkError: Can't find dependent libraries".
According to Dependency Walker and dumpbin, the only dependency is "kernel32.dll", in C:\Windows\System32 and its dependencies, also in System32.
Calling
System.loadLibrary("Kernel32");
returns with no error, but loading the Hello.dll that contains the printing function still throws an error.
Does anyone know what could be causing this?
EDIT:
Dependency Walker does give two warnings/errors:
-Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
-Error: Modules with different CPU types were found.
EDIT:
Here's some more details: I'm running Windows 7 64-bit, and compiling my .dll with cl (Visual Studio 2010).
My Java code Hello.java:
public class Hello
{
public static native void hello();
public static void main(String[] args)
{
hello();
}
static
{
// Extra dependencies load with no error
System.loadLibrary("NTDLL");
System.loadLibrary("KERNELBASE");
System.loadLibrary("KERNEL32");
System.loadLibrary("Hello"); // Throws UnsatisfiedLinkError
}
}
I can compile the java file with no error, and use javah -jni to generate a C header Hello.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Hello_hello
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
I implement the header in Hello.c:
#include <stdio.h>
#include <jni.h>
#include "Hello.h"
#pragma comment(linker, "/EXPORT:Java_Hello_hello=_Java_Hello_hello@8")
JNIEXPORT void JNICALL
Java_Hello_hello(JNIEnv* env, jclass class)
{
printf("Hello World\n");
return;
}
The C code is compiled with cl (though I have also tried tcc) into Hello.dll, which is stored in the same directory as the java .class
Best Answer
It looks like my problem was the combination of a 64-bit system and java installation and 32-bit C compiler.
By default, the Visual C++
cl
compiler generates 32-bit applications, and this caused an error when loaded by 64-bit java. I compiled my application with the Windows SDK 7.1 64-bit compiler, and it ran with no error, as well as removing the warnings in Dependency Walker.