Sun's distribution of the Java Development Kit includes a file in the lib/
directory called
jvm.lib
. This is a Win32 static library against which compilers like VC++ can link. However,
gcc
can't handle the .lib
file (as far as I know), so we need to create a UNIX-y import
library (a .a
file) against which we can link.
In order to do this, I tried to come up with the minimal set of JNI functions that need to be visible to native
programs in order to link. I believe the following list of functions is minimal. Intuitively, it's because these are
the only functions that can be called without having a reference to a pointer returned from one of these three
functions:
- JNI_CreateJavaVM
- JNI_GetDefaultJavaVMInitArgs
- JNI_GetCreatedJavaVMs
Next, we'll create a DLL exports file to use with dlltool
to build an import library. In order to do
that, we'll export the symbols for the functions using the Pascal calling convention. (The numbers after the '@'
sign indicate how many bytes need to be allocated on the stack for arguments.)
Here are the contents of the file:
EXPORTS
JNI_CreateJavaVM@12
JNI_GetDefaultJavaVMInitArgs@4
JNI_GetCreatedJavaVMs@12
By convention, DLL exports files are given the extension .def
, so we'll save this file in our directory
with the name jvm.def
.
Now, we need to generate our import library. We can do that with dlltool
, as follows:
dlltool --input-def jvm.def --kill-at --dllname jvm.dll --output-lib libjvm.dll.a
Naming the output file
libjvm.dll.a
will allow
gcc
to recognize it as a library named
jvm
. The
.dll.a
suffix indicates (by convention) that it is an import library, rather than
a static library (which would simply be named
libjvm.a
, again by convention).
All of that said, I believe the libjvm.dll.a
file would be standard across installations. So if you
don't feel like building your own, you may be able to use mine. (If you try it, please
let me know whether it works.)
Note that in the dlltool
argument list, we don't specify where jvm.dll
is located, or
which one we want to use. The name jvm.dll
is what is embedded in libjvm.dll.a
(and hence in executables we will compile against it); no content from jvm.dll
is used. When a running
program sees a reference to jvm.dll
, it will attempt to locate it at that time. (Each Sun JVM has its own
jvm.dll
, so we can take advantage of this feature to select which VM implementation to use at runtime.)
None of the material in the next two sections (on creating a JVM from C code and invoking a Java class's
main
method) is Cygwin-specific, but we still need a C program which launches a Java program, so we'll
go through that process anyway. If you already have such a program lying around, you may skip to the section
on compiling and executing.