| Implementing Native Methods

## Using a Java Object in a Native Method

> Now that you've got a handle to a Java object in your native method, what can you do with it? You can use it to access the object's member variables. But first, you have to dereference the handle.

> #### Dereferencing the Handle

> > You apply the `unhand()` macro to the object handle to dereference it. When you dereference a handle you get a pointer to a C `struct` that parallels the Java object's structure. For example, to dereference the byte array, named `b`, passed into `InputFile_read()` function you use the `unhand()` macro like this:

> > >     unhand(b)

> > `unhand()` returns a pointer to a C structure. You can use normal C syntax to access the elements in the structure. The elements in the structure parallel the member variables of the objects. Thus, you can access the member variables of an object through the pointer returned from `unhand()`.

> > Note: The `unhand()` macro is defined in the header file `interpreter.h`, which is included in `StubPreamble.h`.

> #### Accessing the Object's Member Variables

> > You can use the pointer returned from `unhand()` like any other C `struct` pointer, accessing its members with the `->` operator.

> > The `b` argument in the `InputFile_read()` function is a byte array. The structure in C that maps to Java arrays contains an element named `body` which is a C array of `char`. The `InputFile_read()` function gets a pointer to the `body` element of `b` with this code:

> > >     char *data = unhand(b)->body;

> > Now that the `InputFile_read()` function has a C pointer to the body of the array, it can gleefully read bytes into it, which it does with this line of code:

> > >     actual = read(unhand(this)->fd, data, actual);

> > The `struct` members have the same names as the corresponding variables in the Java class. So you can use this same mechanism to access an InputFile object's member variables. Indeed, the `InputFile_open()` function uses this mechanism to access an InputFile object's `path` and `fd` variables:

> > >     long InputFile_open(struct HInputFile *this)
> > >     {
> > >         int         fd;
> > >         char        buf[MAXPATHLEN];

> > >         javaString2CString(unhand(this)->path, buf, sizeof(buf));
> > >         convertPath(buf);

> > >         fd = open(buf, O_RDONLY);
> > >         if (fd < 0)
> > >             return(FALSE);

> > >         unhand(this)->fd = fd;
> > >         return(TRUE);
> > >     }

> > Note that the data type of a variable in the C `struct` is the nearest matching C data type to the Java type of the member variable in the object. Be sure to declare and use the structure elements with the correct data types.

> #### Calling Java Methods from a Native Method

> > You can call a Java object's methods from a native method, but you use a different mechanism for that than you use for accessing its member variables. For example, this

> > >     ptr->methodname();   // doesn't work

> > does not work. Rather you use one of the utility functions declared in `interpreter.h` for this purpose.
> > `execute_java_dynamic_method()`
> >   calls an instance method from a native method
> > `execute_java_static_method()`
> >   calls a class method from a native method
> > `execute_java_constructor()`
> >   creates a new Java object from within a native method

> > The character-replacement program doesn't use any of these methods. Let's look at another example that does. The new example program is a collection of methods that illustrate how you can perform various tasks from within a native method. The example program, NativeExample, was generously provided to us by Thomas Ball of the Java team.

> > Let's focus now on the `doubleUp()`method in the NativeExample class. The implementation of the `doubleUp()` method uses `execute_java_constructor()` to create an object from within a native method, and then `execute_java_dynamic_method()` to call one of the object's instance methods. This method returns the object it created.

> > On the Java side, `doubleUp()` is declared like this:

> > >     native NativeExample doubleUp();

> > On the C side, `doubleUp()` is implemented like this:

> > >     struct HNativeExample *
> > >     NativeExample_doubleUp(struct HNativeExample *hInst)
> > >     {
> > >         HNativeExample *hNewInst;
> > >         long twoX;

> > >         hNewInst = (HNativeExample *)execute_java_constructor(
> > >             0, "NativeExample", 0, "(I)", unhand(unhand(hInst)->myValue)->value);

> > >         twoX = (long)execute_java_dynamic_method(
> > >             0, (HObject *)hNewInst, "twoTimes", "()I");

> > >         unhand(unhand(hNewInst)->myValue)->value = twoX;
> > >         return hNewInst;
> > >     }

> > The interesting bits of the `doubleUp()` function are in bold.

> > #### Calling a Java Constructor

> > > Let's look at the first bold line in the code above--the call to `execute_java_constructor()`. The `execute_java_constructor()` function requires four arguments, but may have more.

> > > The first argument to `execute_java_constructor()` is represents the execution context. For now, you should use use `0` for the value of this argument to tell the Java runtime system to use the current execution context. In future releases of Java this argument won't be necessary and will likely be removed.

> > > The second argument is the name of the class you want to instantiate. The example creates a new NativeExample object, so the value of the second argument in that example is the string "NativeExample".

> > > The third argument is the class structure for the class you are instantiating. This argument is redundant because it provides the same information as the second argument--the class to instantiate. However, the `execute_java_constructor()` function must do a class look up if you provide only the class name in the second argument and use `0` for the third argument (as shown in the example). This can cause performance degradation if you are constructing a lot of objects from the same class. If performance is important to you, you can avoid unnecessary class lookups by providing a value for this argument with the `FindClass()` function defined in `interpreter.h`.

> > > You use the fourth argument to specify the Java constructor that you want to invoke. The name of the Java constructor is the name of the class you are instantiating--`NativeExample()` in the example. However, because of method name overloading, you need to be more specific and indicate exactly which constructor you want by specifying the number and type of its arguments. You will also use signature arguments when calling `execute_java_dynamic_method()` and `execute_java_static_method()`.

> > > The example uses the following signature argument, which specifies the NativeExample constructor that takes one integer argument:

> > > >     (I)

> > > The general form of a signature argument is:

> > > >     (arguments)returnvalue

> > > arguments is a series of single keyletters that indicate the data type for an argument. The number of keyletters indicates the number of arguments. returnvalue is a keyletter that indicates the data type of the return value. The keyletters are defined in `signature.h`. Look in that file to find the keyletters that identify other data types such as `float`, `char` and so on. Note that a signature argument used with `execute_java_constructor()` cannot indicate a return value as Java constructors don't return a value.

> > > The general form of `execute_java_constructor()` is:

> > > >     HObject *execute_java_constructor(ExecEnv *env,
> > > >                                      char *classname,
> > > >                                      ClassClass *cb,
> > > >                                      char *signature, ...);

> > > The total number of arguments to the constructor is determined by the signature argument. The signature also indicates which of the classname constructors is called. This function returns the new object, or null if there is an error.

> > #### Calling an Instance Method

> > > After the `doubleUp()` function creates a new NativeExample object with `execute_java_constructor()`, it calls the object's `twoTimes()` instance method:

> > > >     twoX = (long)execute_java_dynamic_method(
> > > >         0, (HObject *)hNewInst, "twoTimes", "()I");

> > > The `execute_java_dynamic_method()` function requires four arguments, but may have more depending on which method you are calling.

> > > The first argument to `execute_java_dynamic_method()` is the same as the first argument to `execute_java_constructor()`--it's the execution context. Again, you should use `0` for the value of this argument to tell the Java runtime system to use the current execution context. In future releases of Java this argument won't be necessary and will likely be removed.

> > > The second argument is the object whose instance method you want to execute. The third argument is the name of the instance method to execute. And finally, the fourth argument is the signature of the instance method. As with `execute_java_constructor()` the signature argument indicates if there are any remaining arguments, how many, and what type. You formulate the signature argument for `execute_java_dynamic_method()` as you did previously with `execute_java_constructor()`.

> > > The general form of `execute_java_dynamic_method()` is:

> > > >     long execute_java_dynamic_method(ExecEnv *env, HObject *obj,
> > > >                                     char *method_name, char *signature, ...);

> > #### Calling a Class Method

> > > To call a class method from a native method use:

> > > >     long execute_java_static_method(ExecEnv *env, ClassClass *cb,
> > > >                                    char *method_name, char *signature, ...);

> > > This function is analogous to `execute_java_dynamic_method` above, except that you provide a class structure instead of an object. You can get the class structure using the `FindClass()` function defined in `interpreter.h`.

| Implementing Native Methods