JNI uses skill points

zhaozj2021-02-16  110

Summary

This article provides practical examples, steps, and guidelines for implementing Java local methods on a 32-bit Windows platform. The example in this article uses the Java Development Kit (JDK) version created by Sun Microsystems.

1.4.1

. The local code written in C is compiled with the Microsoft Visual C compiler.

Introduction

Recently, due to project needs, image conversion function is implemented in the web page, and VC has a unique advantage in image conversion. We first use VC to encapsulate the DLL of the image-converted DLL, and then use JAVA's localization method JNI to call the DLL for image conversion, and finally call the JNI generated DLL with JavaBean.

By finding information on the Internet in recent days, there are a lot of rewards, and the harvest is a summary.

One .Java section

1. No package:

Example 1:

Public Class MyNative

{

Static

{

System.loadLibrary ("MyNative");

}

Public native static void helloword ();

Public Native Static String CTojava ();

}

Description:

1) In the Java program, you must first need to declare the library name called System.LoadLibrary (String Libname) in the class; in the library's search path. The specific operation of the positioning library depends on the operating system. Under Windows, first look up from the current directory, then search the "Path" environment variable listed. If you can't find the library, you will throw unsatisfiedLinkerRor.

2) The DLL generated by JNI is loaded here, not the name of other generated DLLs. Here, the extension name of the library can not be written, is it DLL or SO, which is determined by the system.

3) It also needs to make a local statement on the method to be called, the keyword is Native. And only need to be declared without the need for a specific implementation. • Implementation is implemented in C, will be described later.

4) If static is added, it indicates a static method. If it is not added, it indicates a general method. Adding a parameter in the generated header file. Will explain later.

Now start compiling it:

Compile it with javac mynative.h to generate a corresponding Class file.

With Javah MyNative, you will generate the corresponding MyNative.h header file. The remaining is to start handing over the VC (we use VC to implement the corresponding C implementation part).

2. There is a package:

Example 2:

Package? com..mynchive;

Public Class MyNative

{

Static

{

System.loadLibrary ("MyNative");

}

Public native static void helloword ();

Public Native Static String CTojava ();

}

Others are the same as above, that is, differ from Javac and Javah. For this situation, you must pay attention to this, and my program is not successful at the beginning, and the problem is here.

Javac ./com/mynative/mynative.java

Javah com.mynative.mynative

There is no explanation in one sentence. Explain to one of the following sentences: The front of this class is the name. The header file that is generated is: com.mynative.mynative.h. At the beginning, in this case I used the header file generated by Javah MyNative Always MyNative.h. When checking the information online, I saw the name of the person's head file, my short. But don't know why, now everyone knows why it is. :). Sometimes you need to bring a path. View Javah's grammar. two. C realization

The content generated by Javah Mynative generated as follows:

/ * Do Not Edit this file - IT is Machine Generated * /

#include

/ * Header for class mynative * /

#ifndef _included_mynative

#define _included_mynative

#ifdef __cplusplus

Extern "C" {

#ENDIF

/ *

* Class: MyNative

* Method: HelloWord

* Signature: () V

* /

JNIEXPORT VOID JNICALL JAVA_MYNATIVE_HELLOWORD (JNIENV *, JCLASS);

/ *

* Class: MyNative

* Method: CTOJAVA

* Signature: () ljava / lang / string;

* /

JNIEXPORT JSTRING JNICALL JAVA_MYNATIVE_CTOJAVA? (Jnienv *, jclass); #ifdef __cplusplus

}

#ENDIF

#ENDIF

Next, how to implement it. In fact, things made with JNI are also DLLs, being called by Java.

In the specific implementation, we only care about two function prototypes:

JNIEXPORT VOID JNICALL JAVA_MYNATIVE_HELLOWORD (JNIENV *, JCLASS); and JNIEXPORT JSTRING JNICALL JAVA_MYNATIVE_CTOJAVA (Jnienv *, JCLASS);

Now let's start the first step in exciting:). Select Win32 Dynamic-Link Library in Project, then click Next, the rest of the default. If you don't take the default, there will be a DLLMAIN () function. If you take an empty DLL project, there will be no such function. I am taken here is empty.

Then select New-> File-> C Source? File, generate an empty * .cpp file. We named him for MyNative. Put JNIEXPORT VOID JNICALL JAVA_MYNATIVE_HELLOWORD (JNIENV *, JCLASS); and JNIEXPORT JSTRING JNICAL JAVA_MYNATIVE_CTOJAVA (JNIENV *, JCLASS); copies to the CPP file. Then contain the header file.

The resulting MyNative.cpp content is as follows:

#include

#include "mynative.h"

JNIEXPORT VOID JNICALL JAVA_MYNATIVE_HELLOWORD? (JNIENV * ENV, JCLASS JOBJECT)

{

Printf ("Hello Word! / N");

JNIEXPORT JSTRING JNICALL JAVA_MYNATIVE_CTOJAVAJNIENV * ENV, JCLASS OBJ)

{

JString JSTR;

Char str [] = "Hello, Word! / N"; JSTR = Env-> Newstringutf (STR);

Return JSTR;

}

Be careful before compiling.

Note: Be sure to copy several header files in the Include folder in the SDK (and the header file below the Win32 folder below) to the VC's Include folder. Or set up in the Tools / Options / Directories of the VC, to include the header file.

A little explanation of the program:

1) The foregoing is not said, adding static and not just a difference between a parameter. It is different from JCLASS, and static is Jobject here. JINIEXPORT VOID JNICALL JAVA_MYNATIVE_HELLOWORD (JNIENV * ENV, JOBJECT OBJ).

2) Here JNIEXPORT and JNICALL are keywords of JNI, indicating that this function is to be called by JNI. JString is a type of String type with JNI to communicate with local String and local string, we can turn it, just do string use (specific correspondence is shown in Table). The name of the function is Java_ plus the Package path of the Java program to add a function name (see if there is a package). In the parameter, we only need to care about the parameters existing in the Java program. As for Jnienv * and JCLASS, we generally do not have to touch it.

3) NewStringutf () is a JNI function that creates a new JString object from a CHAR type array containing UTF format coded characters.

4) The above program block JSTR = Env-> Newstringutf (STR); is a write method in C without having to use an ENV pointer. Because the C version of the Jnienv function contains direct insertion member functions, they are responsible for finding the function pointer. For C's writing, it should be changed to: JSTR = (* ENV) -> Newstringutf (ENV, STR); because all JNI functions are called using an ENV pointer, it is the first parameter of any local method. The ENV pointer is a pointer to a function pointer table. Therefore, in each JNI function accessed, the forefix (* ENV) -> is accessed to ensure an indirect reference function pointer.

When transmitting values ​​between C and Java programming languages, it is necessary to understand the correspondence between these values ​​in these two languages. These are in the header file jni.h, with the TypeDef statement to declare the price classes on the target platform. The header file also defines constants such as JNI_FALSE = 0 and JNI_TRUE = 1; Table 1 describes the correspondence between Java type and C type.

Table 1 Java type and C type

Java programming language

C programming language

byte

Boolean

JBOOLAN

1

Byte

JByte

1

charr

Jchar

2

Short

Jshort

2

int

jint

4

Long

Jlong

8

Float

Jfloat

4

Double

JDOUBLE

8

Now start compiling the program written. Select Build-> Rebuild ALL to compile the written program. Click Build-> Build MyNative.dll to generate a DLL file.

You can also compile with the command line CL. See other books.

Also emphasized (once a big injury to this thing): DLL placement place

1) The current directory.

2) Place the path referred to in Path

3) If you set a path in the PATH environment variable, pay attention to the path of the guide to the .dll file, if you refer to .dll, it will be reported.

Let's start testing our writings (assuming that the DLL has been placed correctly). Public class mytest

{

Public static void main (string [] args)

{

Mynative a = new mynative ();

A.helloword ();

System.out.println (a.ctojava ());

}

}

Note Also put myNative.class under the same path to MyTest.java. Now start compiling run mytest, is it output on a DOS window:

Hello Word!

Hello, World!

The above is a simple C program we call through the JNI method. But in the actual situation, it is more complicated than this. Especially when calling other DLLs through JNI, there are many places to pay attention.

Now start to discuss the case where the package is included, the steps are the same as above, just a little bit different. Let's see a function.

JNIEXPORT VOID JNICALL JAVA_COM_MYNATIVE_MYNATIVE_HELLOWORD (JNIENV * ENV, JCLASS JOBJECT)

{

Printf ("Hello Word! / N");

Let's observe the name of the function. The name of the function is Java_ plus the Package path of the Java program to add the functionality name. Now this sentence should be understood.

We also write a program to test the case where the package is included. The program is slightly.

Javac ./com/mynative/mytest.java

Java mytest

Is it also displayed on the DOS window :).

This time, you will here, the next lecture will pay attention to where JNI calls other DLLs, and gives a specific example. A universal function of a Unicode encoding and an ASCII encoding will also be given. If you have any questions, you can communicate with me: Normalnotebook@126.com

转载请注明原文地址:https://www.9cbs.com/read-11556.html

New Post(0)