当前位置:首页 » 编程软件 » javajni编程

javajni编程

发布时间: 2022-04-15 06:38:40

⑴ 用jni在代码中怎样实现java层调c的源码

步骤一:
在java中定义一个c方法的接口 ,相当于在java代码中定义了一个接口 接口的实现方法是C语言实现的。

public native String hello();

步骤二:
实现C代码
方法名 严格按照jni的规范
#include <stdio.h>
#include <jni.h>
jstring Java_com_yys_helloworldformc_MainActivity_hello(JNIEnv* env,jobject obj){
// 2 步 实现C代码
// 返回一个java String 类型的字符串
//jstring (*NewStringUTF)(JNIEnv*, const char*);
//(*env) 相当于 JNINativeInterface* JNIEnv
//*(*env) 相当于 JNINativeInterface
///return (**env).NewStringUTF(env,"helloworldfromc");
return (*env)->NewStringUTF(env,"helloworldfromc");
}

步骤三:
创建android.mk 告诉编译器 如何把c代码打包成函数库

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
# 对应打包成函数库的名字
LOCAL_MODULE := hello
# 对应c代码的文件
LOCAL_SRC_FILES := Hello.c

include $(BUILD_SHARED_LIBRARY)

步骤四:
把c代码 打包成函数库 用到了安装的环境 到相应目录下使用ndk-build打包
5
步骤五:
在java代码中 引入库函数

static{
System.loadLibrary("hello");// 注意事项 去掉前面的lib 后面的.so

}

⑵ 如何用JNI技术提高Java的性能详解

阻碍Java取得广泛使用的一个首要因素是Java程序的运行效率。Java是介于解释型和编译型之间的一种语言,同样的程序,假如用编译型语言C来实现,其运行速度通常要比Java快一倍以上。Java具有平台无关性,这使人们在开发企业级使用的时刻总是把它作为首要候选方案之一,但是性能方面的因素又大大削弱了它的竞争力。为此,提高Java的性能就显得十分主要。 疑问的提出 Sun公司及Java的支撑者们为提高Java的运行速度已经做出了许多全力,其中大多数集中在程序设计的要领和模式挑选方面。由于算法和设计模式的优化是通用的,对Java有效的优化算法和设计模式,对其他编译语言也基本同样适用,因此无法从根本上改动 Java程序与编译型语言在执行效率方面的差别。 JIT(Just In Time,及时编译)技能是个比较好的思想。它的基本原理是:最先议决 Java编译器把Java源代码编译成平台无关的二进制字节码。然后在Java程序真实执行之前,系统议决 JIT编译器把Java的字节码编译为本地化机器码。结尾,系统执行本地化机器码,节省了对字节码实行解释的时间。这样做的优点是大大提高了Java程序的性能,缩短了加载程序的时间;同时,由于编译的结果并不在程序运行间保存,因此也节约了存储空间。缺点是由于JIT编译器对所有的代码都想优化,因此同样也占用了许多时间。 动态优化技能是提高Java性能的另一个尝试。该技能试图议决把Java源程序直接编译成机器码,以充分使用 Java动态编译和静态编译技能来提高Java的性能。该要领把输入的Java源码或字节码转换为经历高度优化的可执行代码和动态库 (Windows中的. dll文件或Unix中的. so文件)。该技能能大大提高程序的性能,但却破坏了Java的可移植性。 JNI技能 实际上,有一种通常为咱们忽视的技能能够在很大程度上处理这个难题,那就是JNI(Java Native Interface, Java本地化要领 )。主张采用纯Java的人们通常反对本地化代码的运用,他们认为在Java程序执行的流程中调用C/C++程序会影响程序的可移植性和安全性。还有一些人认为JNI只是对过去混合编程技能的基本扩展,本来际目标是为了充分使用大量原有的C程序库。 本来,咱们不必拘泥于严格的平台独立性限定,因为采用JNI技能只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎能够不思虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配疑问,咱们完全能够控制代码不出现这种不正确。此外,也不必担心安全控制疑问,因为Java安全模型已扩展为准许非系统类加载和调用本地点法。根据Java规范,从JDK 1. 2开始,FindClass将设法找到与当前的本地点法关联的类加载器。假如平台有关代码属于一个系统类,则无需涉及任何类加载器; 否则,将调用适当的类加载器来加载和链接已命名的类。换句话说,假如在Java程序中直接调用C/C++语言产生的机器码,该部分代码的安全性就由Java虚拟机控制。

⑶ java jni 怎么在windows环境中编译成linux下的so文件

可以直接在android工程下使用,因为android就是linux内核。

  • android的NDK开发需要在linux下进行: 因为需要把C/C++编写的代码生成能在arm上运行的.so文件,这就需要用到交叉编译环境,而交叉编译需要在linux系统下才能完成。

  • 2.安装android-ndk开发包,这个开发包可以在google android : 通过这个开发包的工具才能将android jni 的C/C++的代码编译成库

  • 3.android应用程序开发环境: 包括eclipse、java、 android sdk、 adt等。

  • NDK编译步骤:

  • 选择 ndk 自带的例子 hello-jni ,位于E:android-ndk-r5sampleshello-jni( 根据具体的安装位置而定 ) 。

  • 2.运行 cygwin ,输入命令 cd /cygdrive/e/android-ndk-r5/samples/hello-jni ,进入到 E:android-ndk-r5sampleshello-jni 目录。

  • 3.输入 $NDK/ndk-build ,执行成功后,它会自动生成一个 libs 目录,把编译生成的 .so 文件放在里面。 ($NDK是调用我们之前配置好的环境变量, ndk-build 是调用 ndk 的编译程序 )

  • 4.此时去 hello-jni 的 libs 目录下看有没有生成的 .so 文件,如果有,ndk 就运行正常啦。

⑷ JAVA 里面如何 使用jni 给个例子 加 解释。谢谢

JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。
JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。
简单介绍及应用如下:
一、JAVA中所需要做的工作
在JAVA程序中,首先需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“goodluck”);
}

在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具 体实现。如下:
public native static void set(int i);
public native static int get();
然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
例如程序testdll.java,内容为:
public class testdll
{
static
{
System.loadLibrary("goodluck");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}

用javac testdll.java编译它,会生成testdll.class。
再用javah testdll,则会在当前目录下生成testdll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。
二、C/C++中所需要做的工作
对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。
接上例子。我们先看一下testdll.h文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class testdll */
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
/*
* Class: testdll
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
好,下面我们用testdll.cpp文件具体实现这两个函数:
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll 。把goodluck.dll拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了。

⑸ 请教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编程,现在自己写的dll无法测通,有报错,请帮忙测通,代码如下:

呵呵 我也遇到过这个问题 其实就是C语言的API 跟C++的API有差异而已。

strTemp=env->GetStringUTFChars(env,str,NULL); 这句不能这么写

C语言里要写成 strTemp=(*env)->GetStringUTFChars(env,str,NULL);
C++里 要这么写 strTemp= env->GetStringUTFChars(str,NULL);

下面那两个错误 也这么处理,去掉参数中的env就行了。

return env->NewStringUTF(strTemp);
env->ReleaseStringUTFChars(str,strTemp);

这个还不是jni最难的,我认为JNI最难的是 数组类型参数值的传递(java传给C++或C++传给java),尤其是字符串数组传递。得动态开辟空间,传递后内存释放问题更闹心,搞不清哪个变量归java管不用释放,哪个归C++管需要手动释放。

现在我封装的取生产监控数据的接口,虽然可以用了但还有个问题没解决呢,就是每次程序退出的时候,会报一个内存不可read的系统错误,估计是内存溢出了。不知道怎么处理呢。
我QQ是94254011 有时间交流一下。

⑺ 为什么要用jni的方式来编辑android的程序,相对来讲有什么好处吗相比纯java

android的jni可以使用c/c++来开发,相比java而言,运行的效率提高了很多,特别是在做一些图像算法,或者游戏逻辑的时候,使用jni将大大的提高效率。比如某个游戏要采用opengl,同样加载一个由1000个多边形组成的3d模型,jni要比java运算快好几倍,这样就保证了游戏运行的fps不会太低。
另外一个好处就是内存管理上面,java的内存管理全部由虚拟机来管理,C++由程序员来管理,利用率上面就好多了。
等等其他优点。
既然这么多的优点,为什么一个android程序不采用纯c来开发呢?因为是android的 UI framework采用java,所以,在UI上面还是采用java来开发。

⑻ Java开发中什么情况下要用到JNI技术

  • JNI可以使Java代码和本地的C/C++代码进行交互。

为什么要使用JNI技术:

  1. java无法直接操作硬件, c/c++可以操作硬件,并且效率较高。

  2. java在视频处理,游戏渲染等方面效率不及c/c++。

  3. 避免重复造轮子, 有大量优秀的库,可以复用。

例如:java图形界面程序在最小化后,无法获取全局的键盘和鼠标事件. 需要JNI实现全局热键功能 . java里获取其他窗口的句柄, 并对其他窗口进行控制,也需要JNI技术.

使用了JNI技术缺点是会导致无法跨平台。 需要根据其他平台,再开发本地代码。

JNI实现起来有点复杂. 所以有了JNA技术, 虽然JNA很强大,但是很多功能还是需要JNI来实现的

⑼ 如何通过JNI将java中的对象的地址赋值给c++指针变量

jni编程里, c端 只能操作部分数据类型. 比如

  1. 一般类型.int,char,float

  2. 数组类型, 比如int数组, float 数组.

  3. Buffer类型,比如 intbuffer

  4. String

而你希望的在c里 操作java类...那趁早别想了.人家就没这样的设计.

热点内容
压缩油19 发布:2025-03-17 12:25:29 浏览:854
linux上网代理 发布:2025-03-17 12:23:56 浏览:358
c是高级语言吗 发布:2025-03-17 12:16:31 浏览:522
python泛型 发布:2025-03-17 12:15:01 浏览:481
编程猫被盗 发布:2025-03-17 12:02:18 浏览:130
海关锁密码箱如何设置新密码 发布:2025-03-17 11:53:50 浏览:559
农业卡号的密码在哪里改 发布:2025-03-17 11:48:57 浏览:966
杨澜超级访问 发布:2025-03-17 11:47:17 浏览:237
数据库无损连接 发布:2025-03-17 11:47:16 浏览:13
memcachephp类 发布:2025-03-17 11:40:04 浏览:829