InOnIt.com
Cygwin/Java
FAQ
Calling C from Java
Starting a JVM from C
Overview
Building an import library
Creating a JVM from C
Invoking the class's main() method
Compiling and executing
MLS Playoff Odds
World Football Rankings & World Cup Odds
NCAA Basketball Ratings
Hearts
Personal Home Pages
David's Company

Building an Import Library

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.