您当前的位置:首页 > 互联网教程

后端丨 Java利用JNI调用C++(dllso)函数

发布时间:2025-05-20 18:03:55    发布人:远客网络

后端丨 Java利用JNI调用C++(dllso)函数

一、后端| Java利用JNI调用C++(dll/so)函数

1、Java可以通过JNI技术调用C++函数。具体步骤如下:

2、注意事项:确保Java和C++代码中的数据类型匹配,以避免数据传递错误。在调用C++函数时,注意内存管理和异常处理,以避免内存泄漏或程序崩溃。根据操作系统和编译器的不同,可能需要调整编译和链接选项。

3、通过以上步骤,Java程序可以高效地调用C++函数,从而扩展其性能并利用C++的强大功能。

二、java 调用so文件

1、public staticvoid main(String[] args)

2、System.loadLibrary("HelloWorld");

3、注意print方法的声明,关键字native表明该方法是一个原生代码实现的。另外注意static代码段的System.loadLibrary调用,这段代码表示在程序加载的时候,自动加载libHelloWorld.so库。

4、在当前文件夹编译生成HelloWorld.class。

5、在当前文件夹中会生成HelloWorld.h。打开HelloWorld.h将会发现如下代码:

6、/* DO NOT EDIT THIS FILE- it is machine generated*/

7、/* Header for class HelloWorld*/

8、JNIEXPORT void JNICALL Java_HelloWorld_print

9、该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。

10、创建HelloWorld.c文件输入如下的代码:

11、Java_HelloWorld_print(JNIEnv*env, jobject obj)

12、注意必须要包含jni.h头文件,该文件中定义了JNI用到的各种类型,宏定义等。

13、另外需要注意Java_HelloWorld_print的两个参数,本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。

14、env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C类型的,就是通过调用env方法来完成转换的。

15、obj代表调用的对象,相当于c++的this。当c函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。

16、在Linux下执行如下命令来完成编译工作:

17、cc-I/usr/lib/jvm/java-6-sun/include/linux/

18、-I/usr/lib/jvm/java-6-sun/include/

19、-fPIC-shared-o libHelloWorld.so HelloWorld.c

20、在当前目录生成libHelloWorld.so。注意一定需要包含Java的include目录(请根据自己系统环境设定),因为Helloworld.c中包含了jni.h。

21、另外一个值得注意的是在HelloWorld.java中我们LoadLibrary方法加载的是

22、“HelloWorld”,可我们生成的Library却是libHelloWorld。这是Linux的链接规定的,一个库的必须要是:lib+库

23、名+.so。链接的时候只需要提供库名就可以了。

24、大功告成最后一步,验证前面的成果的时刻到了:

25、如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:

26、java-Djava.library.path='.' HelloWorld

27、当然还有其他的方式可以指明路径请参考《在Linux平台下使用JNI》。

28、我们可以看到久违的“Hello world!”输出了。

三、ndk生成的so怎么在java调用

2.引用别人的静态库,或者动态库来生成新的jni调用库。

我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通过这个列子,我们主要是了解怎么在android的工程中调用jni的库,以及要注意的问题。

第一步:首先我们来看下我们的工程的目录

jni目录是我们生成库的文件,里面包含了一个.mk编译文件以及一系列的.c文件

libs目录是我们编译jni目录下的mk文件动态生成的。

当我们写好了jni下面的库文件以后,在当前目录下执行ndk-build则会自动生成我们需要调用的.so库文件。

第二步: java里面怎么调用jni的库文件,我们先看代码

public class MainActivity extends Activity{

/* A native method that is implemented by the

*'hello-jni' native library, which is packaged

public native String stringFromJNI();

/* this is used to load the'hello-jni' library on application

* startup. The library has already been unpacked into

*/data/data/com.example.HelloJni/lib/libhello-jni.so at

* installation time by the package manager.

System.loadLibrary("hello-jni");

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

System.out.println("*****str:"+ str);

在java文件中要做到调用jni文件生成的so库,需要做到2步