Showing posts with label native method. Show all posts
Showing posts with label native method. Show all posts

Thursday, 24 February 2011

Java Native methods

The Java native method is a great way to gain and merge the power of C or C++ programming into Java. To use Java as a scientific and high performance language, when efficient native Java compilers are not fully implemented, use native method can boost the performance to at least the speed of C compiled code.

1. Write the Java Code (Native Methods)

2. Compile the java code

Use the Java compiler to compile the Java class that you created in the previous step. At this time, you should also compile the main Java application that you wrote to test the native method.

3. Create the .h File

4. Create a Stubs File

5. Write the C Function

6: Create a Dynamically Loadable Library (Native Methods)

7. Run your application

 refer java docs for diagram and details.

4. Create a Stubs File

In addition to the .h file that you generated in the previous step, you must also use javah to generate a stub file. The stub file contains C code that provides the glue that holds the Java class and its parallel C structure together. To generate a stub file use javah's -stubs option. Again remember to run javah on the Java class.
By default, javah will place the resulting stub file in the same directory as the .class file. You can use the -d option to force javah to put the generated stub file in a different directory.
Similar to the .h file that javah generates, the name of the stubs file is the class name with .c appended to the end. In the "Hello World!" example that you've been working with throughout this lesson, the stub file is called HelloWorld.c : 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <StubPreamble.h>

/* Stubs for class HelloWorld */
/* SYMBOL: "HelloWorld/displayHelloWorld()V", Java_HelloWorld_displayHelloWorld_stub */
stack_item *Java_HelloWorld_displayHelloWorld_stub(stack_item *_P_,struct execenv *_EE_) {
extern void HelloWorld_displayHelloWorld(void *);
(void) HelloWorld_displayHelloWorld(_P_[0].p);
return _P_;
}

For the moment, all you really need to know about the stub file is that you will later compile it into the dynamically loadable library that you create in Step 6: Create a Dynamically Loadable Library.

3. Create the .h File

In this step, you use the javah utility program to generate a C header file (a .h file) from the HelloWorld Java class. The header file defines a structure that represents the HelloWorld class on the C side, and provides a C function definition for the implementation of the native method displayHelloWorld() defined in that class.
Run javah now on the HelloWorld class that you created in the previous steps. For example, on UNIX you would issue the following command to your favorite shell tool.
% javah HelloWorld
By default, javah places the new .h file in the same directory as the .class file. You can tell javah to place the header files in a different directory with the -d option. The name of the header file is the Java class name with a .h appended to the end of it. For example, the command shown above will generate a file named HelloWorld.h.
eg. Content of javah file:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <native.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld

typedef struct ClassHelloWorld {
char PAD; /* ANSI C requires structures to have a least one member */
} ClassHelloWorld;
HandleTo(HelloWorld);

extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
#endif

The Class Structure

Look at the header file. Notice that it contains a struct definition for a structure named ClassHelloWorld. The members of this structure parallel the members of the corresponding Java class; that is to say, the fields in the struct correspond to instance variables in the class. But since HelloWorld doesn't have any instance variables, there is just a place holder in the structure. You can use the members of the struct to reference class instance variables from your C functions.

The Function Definition

In addition to the C structure that mimics the Java class, you will also notice a C function signature that looks like this:
extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
This is the definition for the C function that you will write in Step 5: Write the C Function that provides the implementation for the HelloWorld class's native method displayHelloWorld(). You must use this function signature when you write the implementation for the native method. If HelloWorld contained any other native methods, their function signatures would appear here as well. The name of the C function that implements the native method is derived from the package name, the class name, and the name of the Java native method. Thus, the native method displayHelloWorld() within the HelloWorld class becomes HelloWorld_displayHelloWorld(). In our example, there is no package name because HelloWorld is in the default package.
You will notice that the C function accepts a single parameter even though the native method defined in the Java class accepted none. You can think of the parameter as the "this" variable in C++. Our example ignores the "this" parameter. However, the next lesson, , describes how to access the data in the "this" parameter.

5. Write the C Function

Now, you can finally get down to the business of writing the implementation for the native method in C.
The function that you write must have the same function signature as the one you generated with javah into the HelloWorld.h file in Step 3: Create the .h File. The function signature generated for the HelloWorld class's displayHelloWorld() native method looks like this:
extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
Here's our implementation for HelloWorld_displayHelloWorld() which can be found in the file named HelloWorldImp.c.
#include &lt;StubPreamble.h&gt;
#include "HelloWorld.h"
#include &lt;stdio.h&gt;

void HelloWorld_displayHelloWorld(struct HHelloWorld *this) {
printf("Hello World!\n");
return;
}
As you can see, the implementation for HelloWorld_displayHelloWorld() is straightforward: the function uses the printf() function to display the string "Hello World!" and then returns. This file includes 3 C header files:
  • StubPreamble.h which provides enough information to the C code to interact with the Java runtime system. When writing native methods, you must always include this file in your C source files.
  • The .h file that you generated in Step 3: Create the .h File. This file contains the C structure that represents the Java class for which we are writing the native method and the function definition for the native method you are writing in this step.
  • The code snippet above also includes stdio.h because it uses the printf() function.

1. Write the Java Code (Native Methods)

The following Java code segment defines a class named HelloWorld that has one method and a static code segment.
class HelloWorld {
public native void displayHelloWorld();

static {
System.loadLibrary("hello");
}
}

Define a Native Method

You can tell that the implementation for the HelloWorld class's displayHelloWorld() method is written in another programming language because of the native keyword that appears as part of its method definition:
public native void displayHelloWorld();
This method definition provides only the method signature for displayHelloWorld() and does not provide any implementation for it. The implementation for displayHelloWorld() is provided in a separate C language source file. The method definition for displayHelloWorld() also indicates that the method is a public instance method, accepts no arguments and returns no value. For more information about arguments to and return values from native methods see .
Like other methods, native methods must be defined within a Java class.

Load the Library

The C code that implements displayHelloWorld must be compiled into a dynamically loadable library (you will do this in Step 6: Create a Dynamically Loadable Library) and loaded into the Java class that requires it. Loading the library into the Java class maps the implementation of the native method to its definition. The following static code block from the HelloWorld class loads the appropriate library, named hello. The runtime system executes a class's static code block when it loads the class.
static {
System.loadLibrary("hello");
}
The loadLibrary() method is part of the System class.

Create the Main Program

In a separate source file, named Main.java, create a Java application that instantiates HelloWorld and calls the displayHelloWorld() native method.
class Main {
public static void main(String args[]) {
new HelloWorld().displayHelloWorld();
}
}
As you can see from the code sample above, you call a native method in the same manner as you call a regular method: just append the name of the method to the end of the object name with a period ('.'). A matched set of parentheses, ( and ), follow the method name and enclose any arguments to pass into the method. The displayHelloWorld() method doesn't take any arguments.

6: Create a Dynamically Loadable Library (Native Methods)

Remember in Step 1: Write the java Class that you use this method call to load a dynamically loadable library named hello into your program at runtime.
System.loadLibrary("hello");
Now you are ready to create the dynamically loadable library. Use the C compiler to compile the C source code created in the previous steps, HelloWorld.c and HelloWorldImp.c, into a dynamically loadable library named hello.

Saturday, 12 December 2009

Functions or Methods in java

Class behaviour are represented in Java by methods. To declare a method use the following syntax:
[ "public" | "private" | "protected" ] [ "final" ]
[ "static" | "abstract" | "native" ]
return_data_type method_name "(" parameter_list ")"
"{"
// some defining actions
"}"
Accessibility keywords are the same as for properties. The default (ie. omitted) is package (aka friendly) or visible within the current package only.
static methods are shared by all members and exist for all runtime. Static methods can be referenced without creating an instance of the class. abstract methods must be redefined on inheritance. native methods are written in C but accessible from Java.
The return_data_type defines the type of value that the calling routine receives from the object (the reply message in object terminology). It can be any of the primitive types or the reserved word void (default value) if no message is to be returned. The statement return varName; is used to declare the value to be returned to the calling routine.
The parameter_list can contain from zero to many entries of datatype varName pairs. Entries are separated by commas. Parameters are passed by value, thus upholding the encapsulation principle by not allowing unexpected changes or side effects. Object references (such as arrays) can also be passed.
Some examples of method header parameter lists are:
 
public static void example1() {}
public static int add2(int x) {x+=2; return x;}
public static double example3(int x, double d) {return x*d;}
public static void example4(int x, int y, boolean flag) {}
public static void example5(int arr[]) {} // note: this is object

Note: Differences from cpp 
Types of methods
Pass by value or reference