/**************************************************************************** * * Main.java * * This code is used as a driver program to demonstrate the native methods * declared in Native.java. * * This code was developed by Matthew Mead for CS510 Java Implementation. * The countPrimes algorithm was taken from Microsoft's documentation of * their Raw Native Interface (RNI). * * * Updated: * 12-18-98 Added Test #10, passing 2D arrays. * */ class Main { static int a, b; static final int size = 1000000; static final int array_size = 10000; static final int func_calls = 1000000; static final int rectangles = 500; static byte[] c = new byte[size]; static byte[] d = new byte[array_size]; public static void main(String[] args) { String str; long start, stop, elapsed; int t; int x; byte value = 123; // static member Native.z = 47; // Create an object from Native.java Native nat = new Native(); // Simple test System.out.println("\nTest 1: Native.displayHelloWorld"); nat.displayHelloWorld(); // Prints out all members of the Java Object by calling // back into the nat object's 'toString' method System.out.println("\nTest 2: Native.toStringWithPrint"); nat.toStringWithPrint(); // Prints a Java string passed in and also returns a Java string System.out.println("\nTest 3: Native.printLine"); str = "This is from Java"; str = nat.printLine(str); System.out.println("In Java code, string is: " + str); // Prints out the w, x, y, and z members of the nat object // all from native code System.out.println("\nTest 4: Native.printWXYZ"); nat.printWXYZ(); // An array of Rectangles is created and passed to the native code // to be printed System.out.println("\nTest 5: Native.printObjectArray(Rectangle[3])"); java.awt.Rectangle[] rects = new java.awt.Rectangle[3]; for (int i = 0; i < rects.length; i++) rects[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i); nat.printObjectArray(rects, true); // An array of Native objects are passed to C++ for printing // Demonstrates how the native method works on any 'thing' derived // from a Java Object. System.out.println("\nTest 6: Native.printObjectArray(Native[2])"); Native[] nats = new Native[2]; for (int i = 0; i < nats.length; i++) nats[i] = new Native(); nat.printObjectArray(nats, true); // The C++ code allocates and initializes an array of Rectangles // that get passed back to Java and printed here. System.out.println("\nTest 7: Native.returnRectArray(3)"); java.awt.Rectangle[] rects2 = nat.returnRectArray(3); for (int i = 0; i < rects2.length; i++) System.out.println(rects2[i].toString()); // Some exception handling examples // Notice that we must catch 'Throwable' objects and not // Exception objects. It turns out that these tests are // actually returning Error objects, but both Error and // Exception derive from Throwable. System.out.println("\nTest 8: Native.handleException"); try { nat.handleException(); } catch (Throwable e) { System.out.println("Exception in Native code not handled: " + e); } System.out.println("\nTest 9: Native.causeException"); try { nat.causeException(); } catch (Throwable e) { System.out.println("Exception in Native code not handled: " + e); } // 12-18-98 System.out.println("\nTest 10: Native.pass2DByteArray(array2D)"); int dim1 = 2, dim2 = 3; byte count = 0; byte[][] array2D = new byte[dim1][dim2]; for (int i = 0; i < dim1; i++) for (int j = 0; j < dim2; j++) array2D[i][j] = ++count; // Call Native code to initialize an array to a specific value many times nat.pass2DByteArray(array2D); System.out.println("\nIn Java printing array that was changed by native method."); for (int i = 0; i < dim1; i++) for (int j = 0; j < dim2; j++) System.out.println(i + "," + j + " = " + array2D[i][j]); System.out.println("\n\n********** Timings **********\n"); System.out.print("Native countPrimes up to " + size + " ...."); start = System.currentTimeMillis(); nat.countPrimes(c); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); System.out.print(" Java countPrimes up to " + size + " ...."); start = System.currentTimeMillis(); countPrimes(c); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Call a Native 'void func(void)' System.out.print("Native function calls " + func_calls + " ...."); start = System.currentTimeMillis(); for (x = 0; x < func_calls; x++) nat.VoidVoid(); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Call a Java method 'void method(void)' System.out.print(" Java function calls " + func_calls + " ...."); start = System.currentTimeMillis(); for (x = 0; x < func_calls; x++) VoidVoid(); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); t = 1000; // Call Native code to initialize an array to a specific value many times System.out.print("Native initialize array[" + array_size + "] " + t + " times ...."); start = System.currentTimeMillis(); nat.initializeByteArray(d, t, value); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Initialize an array to a specific value many times within Java System.out.print(" Java initialize array[" + array_size + "] " + t + " times ...."); start = System.currentTimeMillis(); for (int i = 0; i < t; i++) for (int j = 0; j < d.length; j++) d[j] = value; stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // From native code, call a constructor for a Java object many times java.awt.Rectangle[] rects4 = new java.awt.Rectangle[rectangles]; for (int i = 0; i < rects4.length; i++) rects4[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i); System.out.print("Native callbacks into Java constructor " + rectangles + " rectangles ...."); start = System.currentTimeMillis(); nat.printObjectArray(rects4, false); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Call a constructor from Java many times java.awt.Rectangle[] rects5 = new java.awt.Rectangle[rectangles]; for (int i = 0; i < rects5.length; i++) rects5[i] = new java.awt.Rectangle(0, 0, 4 * i, 3 * i); System.out.print("Java method calls to constructor " + rectangles + " rectangles ...."); start = System.currentTimeMillis(); printObjectArray(rects5, false); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Call a Java 'void method(void)' from Native code many times System.out.print("Native callbacks to Java void method " + func_calls + " ...."); start = System.currentTimeMillis(); nat.callbackVoid(func_calls); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); // Call a Native 'void func(void)' from Java many times System.out.print("Java calls to Native void function " + func_calls + " ...."); start = System.currentTimeMillis(); for (x = 0; x < func_calls; x++) nat.VoidVoid(); stop = System.currentTimeMillis(); elapsed = stop - start; System.out.println(" " + elapsed + " milliseconds"); } // Test method for function-call overhead public static void VoidVoid() { return; } // Sieving prime numbers public static long countPrimes(byte[] array) { int count = 0; int i; for (i = 0; i < array.length; i++) array[i] = 1; for (i = 2; i < array.length; i++) { if (array[i] != 0) { int k; for (k = i + i; k < array.length; k += i) array[k] = 0; count++; } } return count; } public static java.awt.Rectangle[] returnRectArray(int size) { // Allocate the array of Rectangles java.awt.Rectangle[] array = new java.awt.Rectangle[size]; // Now initialize each one to a Rectangle for (int i = 0; i < size; i++) { // Create a new Rectangle object java.awt.Rectangle element = new java.awt.Rectangle(0, 0, 5 * i, 10 * i); // Assign the Rectangle to an element of the array array[i] = element; } // Return whole array to caller return array; } public static void printObjectArray(Object[] objArray, boolean Print) { // Loop the the array of objects and print out each one using // the 'toString' method of its ancestor class Object for (int i = 0; i < objArray.length; i++) { String s = objArray[i].toString(); if (Print) System.out.println(s); } } }