Part2
JNI数据转换成C数据
e.g. jstring - GetStringUTFChars(), NewStringUTF(), ReleaseStringUTFChars()
1
2
3
4
5
|
JNIEXPORT
void
JNICALL Java_JNISample_sampleFunction(JNIEnv* env, jobject obj, jstring name)
{
const
char
* pname = env->GetStringUTFChars(name, NULL);
env->ReleaseStringUTFChars(name, pname);
}
|
e.g. Array
1
2
3
4
5
6
7
8
9
10
11
12
|
JNIEXPORT jint JNICALL Java_IntArray_sumArray
(JNIEnv *env, jobject obj, jintArray arr) {
jint buf[10];
jint i, sum = 0;
// This line is necessary, since Java arrays are not guaranteed
// to have a continuous memory layout like C arrays.
env->GetIntArrayRegion(arr, 0, 10, buf);
for
(i = 0; i < 10; i++) {
sum += buf[i];
}
return
sum;
}
|
<Refer to> http://ironurbane.iteye.com/blog/425513
JNI的数据定义
1
2
3
4
5
6
7
8
9
10
11
12
|
// In "win\jni_mh.h" - machine header which is machine dependent
typedef
long
jint;
typedef
__int64
jlong;
typedef
signed
char
jbyte;
// In "jni.h"
typedef
unsigned
char
jboolean;
typedef
unsigned
short
jchar;
typedef
short
jshort;
typedef
float
jfloat;
typedef
double
jdouble;
typedef
jint jsize;
|
C++ 调用Java方法
Read: http://stackoverflow.com/questions/819536/how-to-call-java-function-from-c
Windows http://public0821.iteye.com/blog/423941
Linux http://blog.sina.com.cn/s/blog_48eef8410100fjxr.html
JNI数据类型
Java Type | Native Type | Description |
boolean | jboolean | 8 bits, unsigned |
byte | jbyte | 8 bits, signed |
char | jchar | 16 bits, unsigned |
double | jdouble | 64 bits |
float | jfloat | 32 bits |
int | jint | 32 bits, signed |
long | jlong | 64 bits, signed |
short | jshort | 16 bits, signed |
void | void | N/A |
JNI的类型签名
Java Type | Signature |
boolean | Z |
byte | B |
char | C |
double | D |
float | F |
int | I |
long | J |
void | V |
object | Lfully-qualified-class; |
type[] | [type |
method signature | ( arg-types) ret-type |
e.g.
Java side
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
JNISample
{
public
native
void
launchSample();
static
{
System.loadLibrary(
"Sample"
);
}
public
static
int
add(
int
a,
int
b) {
return
a+b;
}
public
boolean
judge(
boolean
bool) {
return
!bool;
}
}
|
C++side
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
JNIEnv *env = GetJNIEnv();
//Get env from JNI
jclass cls;
cls = env->FindClass(
"JNISample"
);
if
(cls !=0)
{
printf
(
"find java class success\n"
);
// constructor
mid = env->GetMethodID(cls,
"<init>"
,
"()V"
);
if
(mid !=0)
{
jobj=env->NewObject(cls,mid);
}
// static function
mid = env->GetStaticMethodID( cls,
"add"
,
"(II)I"
);
if
(mid !=0)
{
square = env->CallStaticIntMethod( cls, mid, 5,5);
}
// function returns boolean
mid = env->GetMethodID( cls,
"judge"
,
"(Z)Z"
);
if
(mid !=0){
jnot = env->CallBooleanMethod(jobj, mid, 1);
}
}
|
查看属性和方法的签名
Java版本 "java -version"
反编译工具 javap:
1
|
javap -s -p -classpath R:\test.Demo
|
Check JNI version
1
2
3
|
#ifdef JNI_VERSION_1_4
printf
(
"Version is 1.4 \n"
);
#endif
|
使用API
1
|
jint GetVersion(JNIEnv *env);
|
返回值需要转换, Need convert the result from DEC to HEX;
JNI实现过程中的Issue
x86 or x64 "Can't load load IA 32-bit dll on a amd 64 bit platform"
确定本机上的默认JVM的版本和动态库的版本一致(x86或x64), Make sure JAVA's default path; check with "java -version" in command line.
3rdParty can't find dependent libraries 保证所依赖的动态库都能被找到;
1) copy the dll into executable file's folder 2) System.load() the dlls by dependecy orders
JNI_CreateJavaVM failed
C++创建JVM调用Java方法
http://docs.oracle.com/javase/1.4.2/docs/guide/jni/jni-12.html#JNI_CreateJavaVM & http://blog.csdn.net/louka/article/details/7318656
[我机器上装了多个版本的Java, 测试的时候没有成功]
jvm.dll(C:\Program Files (x86)\Java\jdk1.7.0_17\jre\bin\client; C:\Program Files (x86)\Java\jdk1.7.0_17\jre\bin\server; need check); jvm.lib(C:\Program Files (x86)\Java\jdk1.7.0_17\lib)
<Refer to> http://home.pacifier.com/~mmead/jni/cs510ajp/ & http://www.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
Sample http://chnic.iteye.com/category/20179
JNI doc http://docs.oracle.com/javase/7/docs/technotes/guides/jni/
>JNA https://github.com/twall/jna/ XstartOnFirstThread
---End---