「jni调用JAVA空指针」java中的空指针

博主:adminadmin 2022-12-22 09:54:11 72

今天给各位分享jni调用JAVA空指针的知识,其中也会对java中的空指针进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

C调用java时使用JNI的问题!急。。。。。

M,是其中的一个组成部分,更详细的看下面:

----------------------------------

操作系统装入jvm是通过jdk中java.exe来完成,通过下面4步来完成jvm环境.

1.创建jvm装载环境和配置

2.装载jvm.dll

3.初始化jvm.dll并挂界到JNIENV(JNI调用接口)实例

4.调用JNIEnv实例装载并处理class类。

在我们运行和调试java程序的时候,经常会提到一个jvm的概念.jvm是java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间.

首先来说一下jdk这个东西,不管你是初学者还是高手,是j2ee程序员还是j2se程序员,jdk总是在帮我们做一些事情.我们在了解java之前首先大师们会给我们提供说jdk这个东西.它在java整个体系中充当着什么角色呢?我很惊叹sun大师们设计天才,能把一个如此完整的体系结构化的如此完美.jdk在这个体系中充当一个生产加工中心,产生所有的数据输出,是所有指令和战略的执行中心.本身它提供了java的完整方案,可以开发目前java能支持的所有应用和系统程序.这里说一个问题,大家会问,那为什么还有j2me,j2ee这些东西,这两个东西目的很简单,分别用来简化各自领域内的开发和构建过程.jdk除了jvm之外,还有一些核心的API,集成API,用户工具,开发技术,开发工具和API等组成

好了,废话说了那么多,来点于主题相关的东西吧.jvm在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的java运行环境,因此也就虚拟计算机. 操作系统装入jvm是通过jdk中java.exe来完成,通过下面4步来完成jvm环境.

1.创建jvm装载环境和配置

2.装载jvm.dll

3.初始化jvm.dll并挂界到JNIENV(JNI调用接口)实例

4.调用JNIEnv实例装载并处理class类。

一.jvm装入环境,jvm提供的方式是操作系统的动态连接文件.既然是文件那就一个装入路径的问题,java是怎么找这个路径的呢?当你在调用java test的时候,操作系统会在path下在你的java.exe程序,java.exe就通过下面一个过程来确定jvm的路径和相关的参数配置了.下面基于windows的实现的分析.

首先查找jre路径,java是通过GetApplicationHome api来获得当前的java.exe绝对路径,c:\j2sdk1.4.2_09\bin\java.exe,那么它会截取到绝对路径c:\j2sdk1.4.2_09\,判断c:\j2sdk1.4.2_09\bin\java.dll文件是否存在,如果存在就把c:\j2sdk1.4.2_09\作为jre路径,如果不存在则判断c:\j2sdk1.4.2_09\jre\bin\java.dll是否存在,如果存在这c:\j2sdk1.4.2_09\jre作为jre路径.如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\“当前JRE版本号”\JavaHome的路径为jre路径。

然后装载jvm.cfg文件JRE路径+\lib+\ARCH(CPU构架)+\jvm.cfgARCH(CPU构架)的判断是通过java_md.c中GetArch函数判断的,该函数中windows平台只有两种情况:WIN64的‘ia64’,其他情况都为‘i386’。以我的为例:C:\j2sdk1.4.2_09\jre\lib\i386\jvm.cfg.主要的内容如下:

-client KNOWN

-server KNOWN

-hotspot ALIASED_TO -client

-classic WARN

-native ERROR

-green ERROR

在我们的jdk目录中jre\bin\server和jre\bin\client都有jvm.dll文件存在,而java正是通过jvm.cfg配置文件来管理这些不同版本的jvm.dll的.通过文件我们可以定义目前jdk中支持那些jvm,前面部分(client)是jvm名称,后面是参数,KNOWN表示jvm存在,ALIASED_TO表示给别的jvm取一个别名,WARN表示不存在时找一个jvm替代,ERROR表示不存在抛出异常.在运行java XXX是,java.exe会通过CheckJvmType来检查当前的jvm类型,java可以通过两种参数的方式来指定具体的jvm类型,一种按照jvm.cfg文件中的jvm名称指定,第二种方法是直接指定,它们执行的方法分别是“java -J”、“java -XXaltjvm=”或“java -J-XXaltjvm=”。如果是第一种参数传递方式,CheckJvmType函数会取参数‘-J’后面的jvm名称,然后从已知的jvm配置参数中查找如果找到同名的则去掉该jvm名称前的‘-’直接返回该值;而第二种方法,会直接返回“-XXaltjvm=”或“-J-XXaltjvm=”后面的jvm类型名称;如果在运行java时未指定上面两种方法中的任一一种参数,CheckJvmType会取配置文件中第一个配置中的jvm名称,去掉名称前面的‘-’返回该值。CheckJvmType函数的这个返回值会在下面的函数中汇同jre路径组合成jvm.dll的绝对路径。如果没有指定这会使用jvm.cfg中第一个定义的jvm.可以通过set _JAVA_LAUNCHER_DEBUG=1在控制台上测试.

最后获得jvm.dll的路径,JRE路径+\bin+\jvm类型字符串+\jvm.dll就是jvm的文件路径了,但是如果在调用java程序时用-XXaltjvm=参数指定的路径path,就直接用path+\jvm.dll文件做为jvm.dll的文件路径.

二:装载jvm.dll

通过第一步已经找到了jvm的路径,java通过LoadJavaVM来装入jvm.dll文件.装入工作很简单就是调用windows API函数:

LoadLibrary装载jvm.dll动态连接库.然后把jvm.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。jvm.dll的装载工作宣告完成。

三:初始化jvm,获得本地调用接口,这样就可以在java中调用jvm的函数了.调用InvocationFunctions-CreateJavaVM也就是jvm中JNI_CreateJavaVM方法获得JNIEnv结构的实例.

四:运行java程序.

java程序有两种方式一种是jar包,一种是class. 运行jar,java -jar XXX.jar运行的时候,java.exe调用GetMainClassName函数,该函数先获得JNIEnv实例然后调用java类java.util.jar.JarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文件:META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。之后main函数会调用java.c中LoadClass方法装载该主类(使用JNIEnv实例的FindClass)。main函数直接调用java.c中LoadClass方法装载该类。如果是执行class方法。main函数直接调用java.c中LoadClass方法装载该类。

然后main函数调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中

“public static void main(String[] args)”方法,并判断该方法是否为public方法,然后调用JNIEnv实例的

CallStaticVoidMethod方法调用该java类的main方法。

另外,虚机团上产品团购,超级便宜

关于java通过jni调用vc++的dll时候的报错

基本用法在后面给你加上了

MinGW是指只用自由软件来生成纯粹的Win32可执行文件的编译环境,它是Minimalist GNU on Windows的略称。详情请参考。

这里的“纯粹”是指「使用msvcrt.dll的应用程序」。无法使用MFC (Microsoft Foundation Classes)。

MinGW:一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时库。

MinGW,即 Minimalist GNU For Windows。它是一些头文件和端口库的集合,该集合允许人们在没有第三方动态链接库的情况下使用 GCC(GNU Compiler C)产生 Windows32 程序。

在基本层,MinGW 是一组包含文件和端口库,其功能是允许控制台模式的程序使用微软的标准C运行时间库(MSVCRT.DLL),该库在所有的 NT OS 上有效,在所有的 Windows 95 发行版以上的 Windows OS 有效,使用基本运行时间,你可以使用 GCC 写控制台模式的符合美国标准化组织(ANSI)程序,可以使用微软提供的 C 运行时间扩展。该功能是 Windows32 API 不具备的。下一个组成部分是 w32api 包,它是一组可以使用 Windows32 API 的包含文件和端口库。与基本运行时间相结合,就可以有充分的权利既使用 CRT(C Runtime)又使用 Windows32 API 功能。

MinGW 官方网站为

实际上 MinGW 并不是一个 C/C++ 编译器,而是一套 GNU 工具集合。除开 GCC (GNU 编译器集合) 以外,MinGW 还包含有一些其他的 GNU 程序开发工具 (比如 gawk bison 等等)。

开发 MinGW 是为了那些不喜欢工作在 Linux(FreeBSD) 操作系统而留在 Windows 的人提供一套符合 GNU 的 GNU 工作环境。

(此前的 cygwin 虽然也是 GNU 的 Windows 移植,但是 cygwin 是有版权的,而不是 GNU。)

所以,使用 MinGW 我们就可以像在 Linux 下一样使用 GNU 程序开发工具。

GCC 就是 MinGW 的核心所在,GCC 是一套支持众多计算机程序语言的编译系统,而且在语言标准的实现上是最接近于标准的。并且 GCC 几乎可以移植到目前所有可用的计算机平台。(我的电脑上就还装有 DevKitPro,里面包含 GCC 的 ARM(for GBA/DS/GP32) 和 MIPS(for PSP) 版本。)

GCC 本身不像 VC 那样拥有 IDE 界面(在 Windows 上也存在 Dev C++ 之类的支持 MinGW 编译器的 IDE)。源代码编辑你可以选用任何你喜欢的文本编辑器(据说微软的开发人员包括 VC 的开发都不用 VC 所带的 IDE 编辑器,而是选用 GNU 的 VIM 编辑器)。然后使用 make 等工具来进行软件项目的编译、链接、打包乃至发布。而像 cvs(svn) 源代码版本控制工具可以让世界上任何一个角落的人都可以参与到软件项目中来。

关于 MFC,微软基础库类,这个随 VC++ 携带的一个源代码公开的开发包,和其他 Windows 程序开发包是一样的。如果有 VC++ 的授权,你完全可以使用 MFC 的源代码,也就是你使用 GCC 来编译 MFC 程序是完全可以的。

当然,GNU 下也很多 Windows 程序开发包,甚至有一些是支持跨平台使用的。不仅仅可以直接把源代码编译为 Windows 程序,也可以不经修改编译为其他操作系统的图形程序。

不过 GNU 下,最流行的图形界面开发库是 GTK+。GTK+ 也能很好的运行在 Windows 平台(比如 GIMP 和 Gaim)。

总体说来,使用 MinGW 就是 GNU。

基本用法:

在mingw环境中生成和使用dll都是十分方便的。

1.生成dll

gcc(g++) -shared -o test.dll test.c(test.cpp)

通过该命令生成test.dll,将导出test.c中非静态的函数和相关的类。

(注by asper:该命令行在处理jni涉及的dll时无效)

我使用微软C++编译器,cl命令对带有空格的路径也是无效的,需要用""括住

2.连接dll到exe中

mingw使用dll的方式和静态库.a的方式是一样的,连接的时候只需要加上-ltest即可,没有lib前缀的要求。

3.编写jni调用的dll

有办法了! 是gcc少了行参数。 如下:

gcc -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -Wl,--add-stdcall-alias -shared -o call.dll call.c

参数:-Wl,--add-stdcall-alias 可以为函数加上标准调用前缀(stdcall @nn)。

这样编译出的dll就可以了。都知道win32中dll中的函数要求有标准调用前缀,在JNI中不方便手动处理这个,Sun又没说清楚这事由编译器办。所以搞得我很郁闷。找了大半个月,终于在一个很古老的网页上找到答案。

基本上和VC的界面差不多 学习C语言用的最多的还是VC++ 6.0

如果对您有帮助,请记得采纳为满意答案,谢谢!祝您生活愉快!

vaela

~~~网络营销,网络炒作,推荐南京新雨恒科技,目前是全国做的最好的!▼3o

eclipse中跑Python代码,会报Java空指针错误

比较简单的是用exec去直接执行.py文件

public static void main(String[] args) throws IOException {

// set up the command and parameter

String pythonScriptPath = "/home/norbert/python/helloPython.py";

String[] cmd = new String[2];

cmd[0] = "python2.6";

cmd[1] = pythonScriptPath;

// create runtime to execute external command

Runtime rt = Runtime.getRuntime();

Process pr = rt.exec(cmd);

// retrieve output from python script

BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));

String line = "";

while((line = bfr.readLine()) != null) {

// display each output line form python script

System.out.println(line);

}

}

python部分扩展包不多的话可以考虑jython,目前这种方式比较推荐,但是jython和python有一定的兼容性问题

还可以用JNI,cython,通过java调C,C调python实现

C回调java几种方法

C代码回调java方法

① 找到字节码对象

//jclass (FindClass)(JNIEnv, const char*);

//第二个参数 要回调的java方法所在的类的路径 "com/itheima/callbackjava/JNI"

② 通过字节码对象找到方法对象

//jmethodID (GetMethodID)(JNIEnv, jclass, const char, const char);

第二个参数 字节码对象 第三个参数 要反射调用的java方法名 第四个参数 要反射调用的java方法签名

javap -s 要获取方法签名的类的全类名 项目/bin/classes 运行javap

③ 通过字节码创建 java对象(可选) 如果本地方法和要回调的java方法在同一个类里可以直接用 jni传过来的java对象 调用创建的Method

jobject obj =(*env)-AllocObject(env,claz);

当回调的方法跟本地方法不在一个类里 需要通过刚创建的字节码对象手动创建一个java对象

再通过这个对象来回调java的方法

需要注意的是 如果创建的是一个activity对象 回调的方法还包含上下文 这个方法行不通!!!回报空指针异常

④ 反射调用java方法

//void (CallVoidMethod)(JNIEnv, jobject, jmethodID, ...);

第二个参数 调用java方法的对象 第三个参数 要调用的jmethodID对象 可选的参数 调用方法时接收的参数

浅谈如何用JNI的代码调用java接口

对于本地函数

JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj)

{

cout"Hello Native Test !"endl;

}

JNIEnv类型代表Java环境。通过这个JNIEnv*指针,就可以对Java端的代码进行操作。如,创建Java类得对象,调用Java对象的方法,获取Java对象的属性等。

JNIEnv的指针会被JNI传送到本地方法的实现函数中来对Java端的代码进行操作

JNIEnv类中的函数:

NewObject/NewString/NewTYPEArray :new新对象

Get/SetTYPEField:获取属性

Get/SetStaticTYPEField :获取静态属性

CallTYPEMethod/CallStaticTYPEMethod

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

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空指针和java中的空指针的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-22,除非注明,否则均为首码项目网原创文章,转载请注明出处。