| Implementing Native Methods

## Returning a Value from a Native Method

> You can return a value of any type from a native method, including primitive types (such as `int`, `float`, and `boolean`), or reference types (such as objects, arrays and strings).

> #### Returning Primitive Types

> > You specify the return type for a native method in the Java definition for the method. The InputFile class has two native methods that return values. The `open()` method returns a boolean and the `read()` method returns an integer.

> > >         // in InputFile.java
> > >     public native boolean open();
> > >     public native int read(byte[] b, int len);

> > The OutputFile class also has two native methods that return values. The `open()` method returns a boolean and the `write()` method returns an integer.

> > >         // in OutputFile.java
> > >     public native boolean open();
> > >     public native int write(byte[] b, int len);

> > As with parameters passed into native methods, the data type of a native method's return value is mapped to the nearest matching C data type. Java booleans and Java integers both map to C longs. So all of these functions return `long` values.

> > >         // in InputFileImpl.c
> > >     long InputFile_open(struct HInputFile *this)
> > >         . . .
> > >     long InputFile_read(struct HInputFile *this,
> > >                         HArrayOfByte *b,
> > >                         long len)

> > >         // in OutputFileImpl.c
> > >     long OutputFile_write(struct HOutputFile *this,
> > >                           HArrayOfByte *b,
> > >                           long len)
> > >         . . .
> > >     long OutputFile_open(struct HOutputFile *this)

> #### Returning Complex Types

> > You can also use a native method's return value to return a reference data type. Neither the InputFile class nor the OutputFile class does this. However, suppose that the `read()` method in the InputFile class returned the bytes read via the method's return value. The Java declaration of that method would be:

> > >         // in InputFile.java
> > >     public native byte[] read(int len);

> > This statement declares that the `read()` method returns an array of bytes. The declaration for the native language function that implements `read()` must return an array of bytes. The return values for reference data types follow the same type rules that arguments of reference data types follow. The native language function must be declared to return a handle to a structure. The structure name is derived from the class name as described in Passing Complex Data Types. Thus the new declaration for the `InputFile_read()` function would be:

> > >         // in InputFileImpl.c
> > >     HArrayOfByte * InputFile_read(struct HInputFile *this,
> > >                         long len)

> #### Returning Data Through Arguments to Native Methods

> > Sometimes, it's more convenient to return data through the arguments to a native method rather than through the return value, such as when you have more than one data value to return.

> > Primitive data types are passed into a native method by value. That is, the value of the argument is put on the call stack not a reference to it. Thus, you cannot return a value from a native method through an argument with a primitive data type--you must return it through an argument with a reference data type. The `read()` method in InputFile does this--it returns the bytes read through its byte array argument. The `InputFile_read()` function gets the bytes from the input file and places them into the body of the byte array.

> > If you want to return a primitive value, consider using the return value of the function. If you really must use an argument to return a primitive value, then you must wrap it in an object.

| Implementing Native Methods