网站首页 > 文章中心 > 其它

java代码给c调用

作者:小编 更新时间:2023-10-23 19:29:15 浏览量:246人看过

写一段java代码,调用c程序,都有什么办法

JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能.解决JAVA对本地操作的一种方法就是JNI.

JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式).通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法.

简单介绍及应用如下:

第一段:JAVA中所需要做的工作

java代码给c调用-图1

在JAVA程序中,首先需要在类中声明所调用的库名称,如下:

static

{

System.loadLibrary("goodluck");

}

今天这一节,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断.

java代码给c调用-图2

还需要对将要调用的方法做本地声明,关键字为native.并且只需要声明,而不需要具体实现.如下:

public

native

void

set(int

i);

int

get();

然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件.

例如程序testdll.java,内容为:

class

testdll

main(String[]

args)

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

#ifndef

_Included_testdll

#define

#ifdef

__cplusplus

extern

"C"

#endif

*

Class:

Method:

get

Signature:

()I

JNIEXPORT

jint

JNICALL

Java_testdll_get

(JNIEnv

*,

jclass);

set

(I)V

Java_testdll_set

jclass,

jint);

在具体实现的时候,我们只关心两个函数原型

这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的.而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用.函数的名称是JAVA_再加上java程序的package路径再加函数名组成的.参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它.

好,下面我们用testdll.cpp文件具体实现这两个函数:

"testdll.h"

i

0;

jclass)

return

i;

j)

j;

编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件.并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll

java代码给c调用-图3

把goodluck.dll拷贝到testdll.class的目录下,java

testdll运行它,就可以观察到结果了.

java如何调用c语言源文件并执行?

JAVA如何调用C函数

要在java中调用c语言的库,需要使用Java提供了JNI.

举例说明

在c语言中定义一个 void sayHello()函数(打印Hello World);然后在Java中调用这个函数显示Hello Word.

现在分别从Java和C语言两部分说明:

① Java 部分

首先定义一个HelloNative,在其中申明sayHello函数,函数要申明为Native 类型的.如下:

public class HelloNative {

public native void sayHello();

编译这个类,生成class文件:

javac HelloWorld.java

利用javah生成需要的h文件

javah HelloNative

生成的 h文件大概如下:

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

#include jni.h

/* Header for class HelloNative */

#ifndef _Included_HelloNative

#define _Included_HelloNative

#ifdef __cplusplus

extern "C" {

* Class: HelloNative

* Method: sayHello

* Signature: ()V

JNIEXPORT void JNICALL Java_HelloNative_sayHello

(JNIEnv *, jobject);

可以看一下上面自动生成的程序,程序include了jni.h,这个头文件在 $JAVA_HOME下的include文件夹下. 还可以发现生成的函数名是在之前的函数名前面加上了Java_HelloNative.

根据上面生成的h文件编写相应的代码实现,建立一个 HelloNative.cpp用来实现显示Hello World的函数.如下:

#include stdio.h

#include "HelloNative.h"

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject)

printf("Hello World!\n");

代码编写完成之后,我们再用gcc编译成库文件,命令如下;

这样就会在当前目录下生成一个libHelloNative.so的库文件.这时需要的库已经生成,在C语言下的工作已经完成了.

此时此刻呢需要在Java中编写一个程序测试一下.在程序前,需要将我们的库载入进去.载入的方法是调用Java的 System.loadLibrary("HelloNative");

public class TestNative

static {

try {

System.loadLibrary("HelloNative");

catch(UnsatisfiedLinkError e) {

System.out.println( "Cannot load hello library:\n " + e.toString() );

public static void main(String[] args) {

HelloNative test = new HelloNative();

test.sayHello();

但是再编译后,运行的时候,问题又出现了.

Cannot load hello library:

java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path

Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V

at HelloNative.sayHello(Native Method)

载入库失败,但是库明明就是放在当前文件夹下的,怎么会载入失败呢?

用System.getProperty("java.library.path")查看,发现java.library.path中并不u存在当前的目录.主要有以下的几个解决办法:

①.) 将生成的库复制到java.library.path有的路径中去,当然这样不是很好

这样之后程序就能够成功的运行了.可以看见显示的"Hello World!"了

Java如何调用C语言代码 ?

以上就是土嘎嘎小编为大家整理的java代码给c调用相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章