jnative对应c语言的char,Java 调用底层接口

本文介绍了Java调用底层接口的三种常见技术:JNI、JNA和JNative。JNI需要编写C/C++代码来实现接口,JNA则允许直接调用,而JNative使用更简洁。通过示例代码展示了每种技术的基本使用步骤,帮助开发者理解它们的工作原理和适用场景。
摘要由CSDN通过智能技术生成

Java 调用底层接口

Java 调用底层接口要通过动态链接库进行,在windows下是dll文件,linux是so文件

Java调用动态库所需要关心的问题:

如何装载文件,以及如何定位所要使用的方法;

数据类型是如何对应的;

如何给使用的方法传递参数;

如何获取返回的值。

目前调用底层接口用的比较多的技术包括jni、jna、jnative、Nativecall等

JNI 封装本地接口

JAVA可以通过JNI接口访问本地的动态连接库,从而扩展JAVA的功能。使用JAVA JNI接口主要包括以下步骤:

²  编写JAVA代码,注明要访问的本地动态连接库和本地方法;

²  编译JAVA代码得到.class文件;

²  使用javah -jni 生成该类对应的C语言.h文件;

²  使用C/C++实现(3)生成的.h文件中声明的各函数;

²  编译C/C++实现代码生成动态连接库。

本文使用一个简单的helloWorld示例演示JNI的使用。

编写JAVA代码

996379fe29bc1bc95e04431840ffb0f5.png

bf8d062f53b1de5e9402c1d69b99f69c.png

1

public

class

helloWorld

2

3

{

4

5

public

native

void

SayHello(String name);

6

7

8

9

static

10

11

{

12

13

System.loadLibrary(

"

jniHelloworld

"

);

14

15

}

16

17

18

19

public

static

void

main(String [] argv)

20

21

{

22

23

helloWorld hello

=

new

helloWorld();

24

25

hello.SayHello(

"

world

"

);

26

27

}

28

}

bf8d062f53b1de5e9402c1d69b99f69c.png

编译JAVA代码

javac helloWorld.java

生成实现函数头文件

javah -classpath . helloWorld

得到的helloWorld.h文件内容如下:

996379fe29bc1bc95e04431840ffb0f5.png

bf8d062f53b1de5e9402c1d69b99f69c.png

1

/*

DO NOT EDIT THIS FILE - it is machine generated

*/

2

3

#include

<

jni.h

>

4

5

/*

Header for class helloWorld

*/

6

7

8

9

#ifndef _Included_helloWorld

10

11

#define

_Included_helloWorld

12

13

#ifdef __cplusplus

14

15

extern

"

C

"

{

16

17

#endif

18

19

/*

20

21

* Class: helloWorld

22

23

* Method: SayHello

24

25

* Signature: (Ljava/lang/String;)V

26

27

*/

28

29

JNIEXPORT

void

JNICALL Java_helloWorld_SayHello

30

31

(JNIEnv

*

, jobject, jstring);

32

33

34

35

#ifdef __cplusplus

36

37

}

38

39

#endif

40

41

#endif

bf8d062f53b1de5e9402c1d69b99f69c.png

在VS中创建工程并实现该函数

996379fe29bc1bc95e04431840ffb0f5.png

bf8d062f53b1de5e9402c1d69b99f69c.png

1

#include

"

helloWorld.h

"

2

3

#include

<

stdio.h

>

4

5

#include

<

string

.h

>

6

7

void

JNICALL Java_helloWorld_SayHello(JNIEnv

*

env, jobject obj, jstring str)

8

9

{

10

11

jboolean b

=

true

;

12

13

char

s[

80

];

14

15

memset(s,

0

,

sizeof

(s));

16

17

strcpy_s(s ,(

char

*

)env

->

GetStringUTFChars(str,

&

b));

18

19

printf(

"

Hello, %s

"

, s);

20

21

env

->

ReleaseStringUTFChars(str , NULL);

22

23

}

bf8d062f53b1de5e9402c1d69b99f69c.png

这是JNI的关键:通过env我们可以使用JAVA提供的一组函数操作与转换函数传递的参数。

编译VC项目得到动态连接库 helloWorld.dll。

把工程输出文件的位置设置成helloWorld类所在的目录,编译之前要把jdk的include目录加到工程属性中

然后在命令行中执行

Java helloWorld 会输出helloWorld

JNA封装本地接口

http://jna.java.net/#demos

996379fe29bc1bc95e04431840ffb0f5.png

bf8d062f53b1de5e9402c1d69b99f69c.png

1

package com.sun.jna.examples;

2

3

4

5

import com.sun.jna.Library;

6

7

import com.sun.jna.Native;

8

9

import com.sun.jna.Platform;

10

11

12

13

/*

* Simple example of JNA interface mapping and usage.

*/

14

15

public

class

HelloWorld {

16

17

18

19

//

This is the standard, stable way of mapping, which supports extensive

20

21

//

customization and mapping of Java to native types.

22

23

public

interface

CLibrary extends Library {

24

25

CLibrary INSTANCE

=

(CLibrary)

26

27

Native.loadLibrary((Platform.isWindows()

?

"

msvcrt

"

:

"

c

"

),

28

29

CLibrary.

class

);

30

31

32

33

void

printf(String format, Object... args);

34

35

}

36

37

38

39

public

static

void

main(String[] args) {

40

41

CLibrary.INSTANCE.printf(

"

Hello, World\n

"

);

42

43

for

(

int

i

=

0

;i

<

args.length;i

++

) {

44

45

CLibrary.INSTANCE.printf(

"

Argument %d: %s\n

"

, i, args[i]);

46

47

}

48

49

}

50

51

}

bf8d062f53b1de5e9402c1d69b99f69c.png

JNA 可以直接调用底层接口,而不用对底层接口进行封装,像例子调用printf一样,底层接口可以通过这种方式直接把接口提供给java调用

Jnative

Jnative用法和jna类似,都是借助于开源项目实现对底层接口的调用,但是用法比jna简单一点,不需要在一个java接口中描述目标文件中的函数与结构,用法如下:

建立test_say.java文件,需要配置好JNative.jar包

996379fe29bc1bc95e04431840ffb0f5.png

bf8d062f53b1de5e9402c1d69b99f69c.png

1

import

org.xvolks.jnative.JNative;

2

3

import

org.xvolks.jnative.Type;

4

5

import

org.xvolks.jnative.exceptions.NativeException;

6

7

import

org.xvolks.jnative.pointers.Pointer;

8

9

import

org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

10

11

import

org.xvolks.jnative.pointers.memory.NativeMemoryBlock;

12

13

import

org.xvolks.jnative.util.Callback;

14

15

//

import org.xvolks.test.callbacks.linux.LinuxCallback;

16

17

18

19

public

class

test_ helloWorld {

20

21

private

final

static

String LIB_NAME

=

"

msvcrt

"

;

//

自动判断.so 或者.dll

22

23

24

25

public

static

void

main(String[] args)

throws

NativeException, IllegalAccessException {

26

27

try

{

28

29

JNative printf

=

new

JNative(LIB_NAME,

"

printf

"

);

30

31

printf.setParameter(

0

,”hello world”);

32

33

printf.invoke();

34

35

}

36

37

catch

(Exception e)

38

39

{

40

41

e.printStackTrace();

42

43

}

44

45

}

46

47

}

bf8d062f53b1de5e9402c1d69b99f69c.png

转自: http://www.cnblogs.com/shapherd/archive/2011/03/05/1971636.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值