您的位置:首页 > 编程语言 > C语言/C++

C++ 通过jni生成库供JAVA调用(下)--C++生成库并JAVA可以调用(windows)

2017-08-29 22:34 489 查看

C++ 通过jni生成库供JAVA调用(下)–C++生成库并JAVA可以调用(windows)

项目上 JAVA通过C++库去调用硬件设备,需要用C++封装库,然后JAVA调用C++的库,这里描述JAVA调用C++库的过程。

这里实现C++生成库可让JAVA通过JNI去调用

编译环境:VS2015; eclipse/(使用命令行也操作可行,eclipse不熟悉,然后开始没有使用它)

语言: C++, JAVA

这个过程中遇到了一些坑,JAVA也是只会写个hello world ,然后在java调用库的时候会出现一些问题。

使用notepad++建立个.java文件,输出所需要实现的一些接口

使用文本来实现.java文件

在java文件里面声明在C++里面需要实现的接口或者已经存在的接口,数据类型需要适当的转换。

在D:\jni\java_jni\java_jni下建立个文件jniCppSDK.java

并输入一下内容

package java_jni;

public class jniCppSDK {
public native void sayHello();
public native int sum(int a, int b);
public native int max(int a, int b, int c);
static
{
System.loadLibrary("jniCppSDK");
}
public static void main(String[] args)
{
jniCppSDK test = new jniCppSDK();

test.sayHello();
System.out.println(test.sum(10, 21));

4000
System.out.println(test.max(10, 12, 20));

System.out.println("hello JAVA");
}
}


或者使用eclipse来实现.java文件

该步骤和上个步骤的目的是一样的

打开eclipse – File – New – Java Project( 保存路径为
D:\jni\java_jni\java_jni_eclipse
,工程名称:
java_jni_eclipse
) – Next – Finish

在src处右键 New – Package ,Name 更改为
java_jni


在java_jni包处右键 New – Class , Class名字设置为
jniCppSDK


在jniCppSDK.java文件里面可以看到内容:

package java_jni;

public class jniCppSDK {

}


将之前代码添加到该Class里面

package java_jni;

public class jniCppSDK {
public native void sayHello();
public native int sum(int a, int b);
public native int max(int a, int b, int c);
static
{
System.loadLibrary("jniCppSDK");
}
public static void main(String[] args)
{
jniCppSDK test = new jniCppSDK();

test.sayHello();
System.out.println(test.sum(10, 21));
System.out.println(test.max(10, 12, 20));

System.out.println("hello JAVA");
}
}


利用javah 生成jni头文件

C++代码实现头文件这些接口,然后可以生成JAVA可以调用的库了

对使用notepad++之类的文本编辑器,进行操作

在jniCppSDK .java文件路径下,按住shift键+鼠标右键,点击在此处打开Powershell窗口,输出
javac jniCppSDK.java
,可以看到文件夹里面多出了jniCppSDK.class文件

由于.java文件使用
package java_jni;
声明,需要在java文件的父路径上进行操作,在shell里面输出
cd ../
, 路径会回到
D:\jni\java_jni
里面,然后输入
javah java_jni.jniCppSDK
,来生成jni头文件,然后会在该路径下出现
java_jni_jniCppSDK.h
文件

如果java文件里面没有package的声明的话,直接在java文件所在路径下
javah java_jni.jniCppSDK
就可以了,因为java文件里面有
package java_jni;
所以在生成头文件的时候需要在java文件的上层目录下进行操作

对使用eclipse的java文件操作

进入到eclipse工程里面,到
D:\jni\java_jni\java_jni_eclipse\src\java_jni
路径下,然后进入Powershell路径下’javac jniCppSDK.java’

然后
cd ../
,到上级目录下,运行
javah java_jni.jniCppSDK
,然后该路径下会出现

java_jni_jniCppSDK.h
文件,

上面两种情况下生成 jni头文件,比较两种状况下得到的jni头文件,两者完全一样。

通过jni头文件和C++里面的程序进行对接

VS工程环境搭建

D:\jni\java_jni
里面,创建win32控制台的工程,工程名称为jniCppSDK,程序类型选择DLL,空项目。

java_jni_jniCppSDK.h
头文件添加到工程头文件里面,将
testSDK.cpp
工程源文件(可以自己新建个源文件)

// testSDK.cpp : 定义 DLL 应用程序的导出函数。
//
#include <iostream>
#include "java_jni_jniCppSDK.h"

void helloSDK()
{
std::cout << "hello sdk" << std::endl;
}
int mySum(int a, int b)
{
return (a + b);
}
int myMax(int a, int b, int c)
{
int max = a;

if (max < b)
max = b;
if (max < c)
max = c;

return max;
}


此时编译的话,会出现无法打开 源 文件 “jni.h”的情况,需要将java的jni路径添加到附加包含目录配置属性C/C++附加包含目录 添加
C:\Program Files\Java\jdk1.8.0_144\include\;C:\Program Files\Java\jdk1.8.0_144\include\win32
,

注意:x86平台和x64平台的设置,可能是目录添加到x86里面,缺以x64平台运行的,所有还是会找不到
jni.h
文件,所以我两个平台都添加了附加包含目录。

添加Source.def文件,输入以下内容,否则的话,链接不到方法。

LIBRARY "jniCppSDK"
EXPORTS
Java_java_1jni_jniCppSDK_sayHello @1
Java_java_1jni_jniCppSDK_sum @2
Java_java_1jni_jniCppSDK_max @3


编写代码

testSDK.cpp与生成的jni头文件接口对接,完成之后的代码:

// testSDK.cpp : 定义 DLL 应用程序的导出函数。
//
#include <iostream>

#include "java_jni_jniCppSDK.h"

void helloSDK()
{
std::cout << "hello sdk" << std::endl;
}
int mySum(int a, int b)
{
return (a + b);
}
int myMax(int a, int b, int c)
{
int max = a;

if (max < b)
max = b;
if (max < c)
max = c;

return max;
}

/*
* Class:     java_jni_jniCppSDK
* Method:    sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_1jni_jniCppSDK_sayHello
(JNIEnv *, jobject)
{
helloSDK();
}

/*
* Class:     java_jni_jniCppSDK
* Method:    sum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_java_1jni_jniCppSDK_sum
(JNIEnv * env , jobject obj, jint a, jint b)
{
return (jint)(mySum((int)a, (int)b));
}

/*
* Class:     java_jni_jniCppSDK
* Method:    max
* Signature: (III)I
*/
JNIEXPORT jint JNICALL Java_java_1jni_jniCppSDK_max
(JNIEnv * env, jobject obj, jint a, jint b, jint c)
{
return (jint)(myMax((int)a, (int)b, (int)c));
}


编译运行,生成dll文件。

将dll文件放到
D:\jni\java_jni
路径下,命令行下运行java程序

D:\jni\java_jni> java java_jni.jniCppSDK


运行结果:

hello sdk
31
20
hello JAVA


将dll文件丢到eclipse工程路径下运行

运行结果:

hello sdk
31
20
hello JAVA




java调用C++库成功

附上测试源码:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: