|
[ This exercise
| Solution
| Course Notes
| Exercises page
]
|
|
Help: Exercise 1 |
MathFuncs.java Create the java class that declares the native method. For this exercise, the java class definition is trivial. There are no members or methods defined within the class. There are 2 key points here:
- Make sure to include the native keyword when declaring the native method, otherwise, it's just another java method and the javah tool won't create the correct header file.
- Also, be sure that the name of the shared library is correct.
class MathFuncs { public native double calculateAreaOfCircle(double radius); static { System.loadLibrary("MathFuncsImp"); } }
Main.java Create the java class that will test the native method.
class Main
{
public static void main(String[] args)
{
MathFuncs mf = new MathFuncs();
double radius = 10.0;
double area = mf.calculateAreaOfCircle(radius);
System.out.println("Area of circle with radius " + radius " is " + area);
}
}
Compile MathFuncs.java and Main.java using javac:
javac MathFuncs.java javac Main.javaThis, of course, produces MathFuncs.class and Main.class.
Using javah, create the C/C++ header file that represents the java MathFuncs class. Be sure to include the -jni switch so that the resulting header file is a JNI-compatible file. Also, don't include the .class extension:javah -jni MathFuncsThis creates a file called MathFuncs.h in the same directory as MathFuncs.class:/* DO NOT EDIT THIS FILE - it is machine generated */ #include < jni.h > /* Header for class MathFuncs */ #ifndef _Included_MathFuncs #define _Included_MathFuncs #ifdef __cplusplus extern "C" { #endif /* * Class: MathFuncs * Method: calculateAreaOfCircle * Signature: (D)D */ JNIEXPORT jdouble JNICALL Java_MathFuncs_calculateAreaOfCircle (JNIEnv *, jobject, jdouble); #ifdef __cplusplus } #endif #endifIt is important that you compile MathFuncs.java in the previous step so that the .class file is available to javah in this step.
This is where the real work is done, which is why we have native methods in the first place. There are 4 key points:If you have problems at run-time, they are likely to be caused by this function signature. The safest thing to do to ensure that you won't have any problems is to copy the declaration of the function from the header file generated by javah.
- #include the header file that was created in the previous step.
- Make sure that you prepend Java_MathFuncs_ to the name of the method.
- Check that the return type and argument types match the declaration in MathFuncs.h. If they don't match, you won't get any warnings from the compiler, but at run-time, when java calls the method, it will fail.
- Don't forget the first two parameters to the function. They are required, even if they are not used (as in this exercise.)
#include "MathFuncs.h" JNIEXPORT jdouble JNICALL Java_MathFuncs_calculateAreaOfCircle(JNIEnv *env, jobject obj, jdouble radius) { const jdouble PI = 3.1415926535; jdouble area = PI * (radius * radius); return area; }
This is the step where the actual creation of the shared library happens. It is also the point where we must name the file. It is important that the name matches what the MathFuncs class is expecting when it loads the shared library in its static initialization:This code is taken from MathFuncs.java:
static { // The name of our shared library must match what // the class is loading at initialization time: System.loadLibrary("MathFuncsImp"); }Here is an example of how to make a shared library under Unix:
# This works on sirius.cs.pdx.edu # The -o option allows you to name the shared library. Note that # you must provide the 'lib' prefix and '.so' suffix here. gcc -G -I/pkgs/jdk1.1.1/include -I/pkgs/jdk1.1.1/include/solaris MathFuncsImp.cpp -o libMathFuncsImp.soHere is an example of how to make a shared library under Windows NT:
: This works under NT. Replace the include paths to match your environment : and be sure to include Sun's JDK not Microsoft's! : Note that you must provide the .dll extension (case insensitive) cl -Im:\jdk1.1.5\include -Im:\jdk1.1.5\include\win32 -LD MathFuncsImp.cpp -FeMathFuncsImp.dll
To execute the program, run Main with the java interpreter:java MainThe output should look something like this:Area of circle with radius 2 is 25.132741228If you receive an error message such as either of these:java.lang.UnsatisfiedLinkError: no MathFuncsImp in shared library path java.lang.UnsatisfiedLinkError: calculateAreaOfRectanglerefer to the common mistakes in the detailed example.
|
Copyright © 1998
Sergio Antoy.
All Rights Reserved February 99, version 020199 |