Java调用c++库

JNI和Native两种方法  添加JNA方法

JNI

1、JNI简介

JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

2、使用方法

a) 创建java文件:NativeTest.java。内容如下:

package com.bj58;

public class NativeTest {

public native int add(int x, int y);

}

进入项目目录,编译NativeTest.java。命令:

javac  NativeTest.java

生成此方法对应的c++的头文件, com_bj58_NativeTest.h。命令:

javah com.bj58.NativeTest  //这里是类名

必须在com同级目录下如上执行命令,执行后,可在此目录下生成.h文件;如果是eclipse就在bin目录下执行。

b)  com_bj58_NativeTest.h类容如下:


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

#include <jni.h>

/* Header for class com_bj58_NativeTest */



#ifndef _Included_com_bj58_NativeTest

#define _Included_com_bj58_NativeTest

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     com_bj58_NativeTest

 * Method:    add

 * Signature: (II)I

 */

JNIEXPORT jint JNICALL Java_com_bj58_NativeTest_add

  (JNIEnv *, jobject, jint, jint);



#ifdef __cplusplus

}

#endif

#endif


这一部分自动生成,没什么可说的。

c) 根据com_bj58_NativeTest.h 写相应的.cpp文件;


#include "com_bj58_NativeTest.h"

#include <iostream>

using namespace std;

JNIEXPORT jint JNICALL Java_com_bj58_NativeTest_add

  (JNIEnv * env, jobject obj, jint x, jint y)

{

return x + y;

}

其中在com_bj58_NativeTest.h中有一个#include <jni.h>

此头文件在 %JAVAHOME%/include中,将其copy到你的项目,将<>改为””;打开jin.h文件,其中有一个jni_md.h文件,也将其拷贝到你的项目下;

因为最终要生成动态链接库供java调用,因此如何生成DLL也很重要。

最终生成NativeTest.dll。

d) 调用,在第一步NativeTest.java中实现调用,如:

public class NativeTest {

static{

System.loadLibrary("NativeTest"); //c++的dll名

}

public native int add(int x, int y);



public static void main(String[] args) {

NativeTest test = new NativeTest();

System.out.println(test.add(20, 48));

}

}

其中System.loadLibrary("NativeTest"); 是将此DLL加载到java程序,

NativeTest.dll要放置在系统环境变量下,比如System32下;

也可以用System.load(“c:\\NativeTest.dll”);


至此完成,运行即可调用。


JNative

1、JNative简介

JNative是基于JNI的一个开源实现工具。可以根据现有的DLL直接调用内部方法。

2、使用方法

a) 将现有的dll放在系统环境变量中,如System32;或者在调用的时候使用

System.load(“c:\\NativeTest.dll”);

我的dll生成文件:

NativeTest.h :

#ifndef NATIVETEST_H

#define NATIVETEST_H

extern "C" int __declspec(dllexport)add(int x, int y);

#endif

NativeTest.cpp :

#include "NativeTest.h"



int add(int x, int y) {

return x + y;

}

最终生成NativeTest.dll


b) 调用

public int add(int x, int y) {

JNative PegRoute = null; 

try {  

            if (PegRoute == null) {  

System.load("C:\\Users\\58\\Desktop\\jnative\\NativeTest.dll"); //加载dll

 // 1. 利用org.xvolks.jnative.JNative来加载DLL:参数1.NativeTest为类名  

                // 2.add方法名  

       PegRoute = new JNative("NativeTest", "add");  

                // 2.设置要调用方法中的参数:0 表示第一个以此类推   

       PegRoute.setParameter(0,Type.INT, String.valueOf(x));  

       PegRoute.setParameter(1, Type.INT, String.valueOf(y));  

                // 3.设置返回参数的类型  

                PegRoute.setRetVal(Type.INT);  

                // 4.执行方法  

                PegRoute.invoke();// 调用方法  

            }  

            System.out.println("调用的DLL文件名为:" + PegRoute.getDLLName());  

            System.out.println("调用的方法名为:" + PegRoute.getFunctionName());  

            System.out.println("返回值为:" + PegRoute.getRetVal());  

            // 5.返回值  

            return Integer.parseInt(PegRoute.getRetVal());  

            

        } catch (NativeException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} finally {  

            if (PegRoute != null) {  

                // 6.释放系统资源  

try {

PegRoute.dispose();

} catch (NativeException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

            }  

        }

return 0;  

}

需加载JNative.jar,官网下载即可


至此完成调用

JNA


JNA调用c++库则更为简单。库我们依然使用jnative中生成的c++库NativeTest.dll。

import com.sun.jna.Library;
import com.sun.jna.Native;

public class JNATest {
	
	static {
		System.load("C:\\Users\\58\\Desktop\\jnative\\NativeTest.dll");
	}
	/**
	 * 定义库中所含接口
	 * 
	 * */
	public interface NativeTest extends Library {
		public int add(int x, int y);
	}

	public static void main(String[] args) {
		
		//导入库
		NativeTest nt = (NativeTest) Native.loadLibrary("NativeTest",
				NativeTest.class);
		if (nt != null) {
			int x = nt.add(10, 36);//具体调用
			System.out.println(x);
		}
		
	}
	
}
至此完成调用

Vs2010生成dll方法

JNative官网

转载于:https://my.oschina.net/le284/blog/109865

### Java 调用 C++ 的方法 通过Java Native Interface (JNI),可以在Java应用程序中调用本地方法,这些方法由C或C++编写并编译成动态链接(DLL)[^1]。具体过程涉及几个重要步骤: #### 创建Java类定义native方法 创建一个新的Java类`TestJavaCallC`来声明一个原生方法`sayHello()`,该方法将在C++代码中实现。 ```java package Test; public class TestJavaCallC { public native void sayHello(); public static void main(String[] args){ System.loadLibrary("NativeCode1"); TestJavaCallC tNative = new TestJavaCallC(); tNative.sayHello(); } } ``` 这段代码展示了如何声明一个名为`sayHello`的本地方法以及加载所需的本地。 #### 编写对应的C++函数 对于上述Java中的每一个`native`方法,在C++端都需要有一个相应的实现。假设已经生成了头文件,则可以按照下面的方式去完成具体的逻辑处理: ```cpp #include "jni.h" #include <iostream> using namespace std; // 假设这是从javah工具自动生成得到的签名 extern "C" JNIEXPORT void JNICALL Java_Test_TestJavaCallC_sayHello(JNIEnv* env, jobject obj) { cout << "Hello from C++!" << endl; } ``` 这里需要注意的是,如果是在Windows环境下开发DLL的话,可能还需要额外指定导出符号以便让Java找到对应的方法入口[^2]。 #### 加载共享 为了使Java能够访问到所写的C++功能模块,需要确保在运行时可以通过`System.loadLibrary()`成功加载这个外部资源。通常情况下,这指的是将`.so`(Linux/Unix), `.dylib`(Mac OS X) 或者 `.dll`(Microsoft Windows) 文件放置于系统的标准路径下或者是当前工作目录内。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值