您的位置:首页 > 理论基础 > 计算机网络

http://stuf.ro/calling-c-code-from-java-using-jni

2016-03-09 06:26 417 查看
In this tutorial we'll be creating a Java application calling code from a native library. We'll have a Java application called HelloWorld which will call the function
helloFromC
from
a shared library named
ctest
, using Java Native Interface.
First off, we'll create a file named
HelloWorld.java
to contain the
HelloWorld
class.
/* HelloWorld.java */

public class HelloWorld {
native void helloFromC(); /* (1) */
static {
System.loadLibrary("ctest"); /* (2) */
}
static public void main(String argv[]) {
HelloWorld helloWorld = new HelloWorld();
helloWorld.helloFromC(); /* (3) */
}
}


Make the virtual machine aware of a function defined externally, named "helloFromC"
Load an external library called "ctest" (which will need to define this function)
Call the function we talked about

Even though we didn't write any library yet, we can still compile the Java application, because this is a dependency that will be resolved at runtime. So, let's compile the application:
javac HelloWorld.java

This will generate a
HelloWorld.class
file containing the application. Running the application will now result in an error, as we expect, because
the library is not created yet:
java HelloWorld

Exception in thread "main" java.lang.UnsatisfiedLinkError: no ctest in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1754)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at HelloWorld.(HelloWorld.java:6)

Alright, let's now start writing the
ctest
library in C. To do that, we must first generate a header file from the
.class
file
we created earlier. This header file will contain the definition of the function as it must be present in the C file.
javah HelloWorld

This command will generate a HelloWorld.h file in the same directory, containing the following code:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     HelloWorld
* Method:    helloFromC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

We'll leave this file exactly as is, as the comment suggests, but we need to copy the function definition. Copy the definition and put it in a new file, named
ctest.c
:
/* ctest.c */

JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv * env, jobject jobj)
{
}

Note that we gave names to the parameters. Now let's implement the function. Aside from our own includes, we also need to include
jni.h
for this to
work. So, modify the
ctest.c
file to contain something like:
/* ctest.c */

#include <jni.h>
#include <stdio.h>

JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv * env, jobject jobj)
{
printf("Hello from C!\n");
}

Now that we have the file, let's compile it and create a native library. This part is system dependent, but the only things that change really are the extension of the generated library file and the path to the
jni.h
include.
gcc -o libctest.so -shared -I/path/to/jdk/headers ctest.c -lc

Replace
.so
with
.dylib
if you're on a Mac, or
.dll
if
you're on Windows (remove the
lib
part from the file name as well if you're on Windows). Also, replace
/path/to/jdk/headers
with
the full path to the directory containing the file
jni.h
. If you don't know where that is, you can use the locate
jni.h
command
on UNIX-like systems.
Once you successfully run the above command, you will see a
libctest.so
file in the current directory (or
libctest.dylib
or
libctest.dll
).
If you remember from the Java code you wrote earlier, the virtual machine will expect a library named
ctest
to reside in the current directory (point 2). By
that, it means that a file with the name
libctest.so
should be here, which you just created.
To see this in action, run the application:
java HelloWorld

If everything works correctly, you should see:
Hello from C!


原文地址: http://stuf.ro/calling-c-code-from-java-using-jni
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: