请教JNI编程中C调用Java实现中NullPointerException问题

Python020

请教JNI编程中C调用Java实现中NullPointerException问题,第1张

java 与 C++ 两种编程语言,它们之间的相互调用:

1、java 调用C++编写的dll,可使用JNI 或 Jawin 开源项目(推荐第二种方法)。

2、C++ 调用java 的变量、方法,通过JNI (Java Native Interface)与java类交互。

----操作步骤(只总结第二个)-----

(1) vc6.0编译C++程序,开发环境设置:工具--》选项--》工具,工具标签下:选择“include files”,加入头文件目录:C:\Program Files\Java\jdk1.5.0\include 和 C:\Program Files\Java\jdk1.5.0\include\win32 ;选择“Libary files"下,加入LIB目录:C:\Program Files\Java\jdk1.5.0\lib 。会编译成exe文件。

执行程序环境设置: Path环境变量加入:C:\Program Files\Java\jdk1.5.0\jre\bin\client (jvm.dll所在目录),若不加入path会提示,执行时找不到jvm.dll.

(2)GetStaticMethodID(cls,"main","([Ljava/lang/String)V")

//([Ljava/lang/String)V 是main()签名

在java程序目录下执行:javap -s -p ClassDemo (注:ClassDemo.java 已经编译)

取main 下面的语句 :: Signature: ([Ljava/lang/String)V

(3)附代码示例:

java程序

import java.io.*

public class DemoMain{

public static void main(String[] args) throws java.io.IOException, java.lang.NullPointerException

{

System.out.println("This is a test.")

}

}

C++程序:

#ifndef __cplusplus

#define __cplusplus

#endif

#include "jni.h"

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#pragma comment (lib,"C:\\Program Files\\Java\\jdk1.5.0\\lib\\jvm.lib") // 动态调用lib

#pragma warning(disable: 4129) // 关闭 warning, 4129

void main() {

LoadLibrary("C:\\Program Files\\Java\jre1.5.0\\bin\\client\\jvm.dll")// 动态调用dll

JavaVM *jvm

JNIEnv *env

JavaVMInitArgs vm_args

JavaVMOption options[3]

options[0].optionString = "-Djava.compiler=NONE"

options[1].optionString = "-Djava.classpath=."

options[2].optionString = "-verbose:jni"

vm_args.version = JNI_VERSION_1_4

vm_args.nOptions = 3

vm_args.options = options

vm_args.ignoreUnrecognized = JNI_TRUE

jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)// 创建虚拟机

if (res <0) {

fprintf(stderr, "Can't create Java VM\n")

exit(1)

}

jclass cls = env->FindClass("DemoMain")

if (cls == 0) printf("Sorry, I can't find the class")

fprintf(stdout, "This is invokeSimplified4.\n")

jmethodID get_main_id

if(cls != NULL)

{

get_main_id =env->GetStaticMethodID(cls,"main","([Ljava/lang/String)V")

fprintf(stdout, "This is invokeSimplified5.\n")

if(get_main_id != NULL )

{

jclass string = env->FindClass("java/lang/String")

jobjectArray args = env->NewObjectArray(0,string, NULL)

fprintf(stdout, "This is invokeSimplified6.\n")

int i = env->CallIntMethod(cls, get_main_id, args)

fprintf(stdout, i+ "This is invokeSimplified7.\n")

}

}

jvm->DestroyJavaVM()

fprintf(stdout, "Java VM destory\n")

}

是的,jni调用时, java和c是同个线程

检测方法:在java和c中分别把当前线程的id输出出来查看。

Java获取线程Id:

Thread.currentThread().getId()

C中获取线程Id:

GetCurrentThreadId()