`
sea878412
  • 浏览: 24147 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java 通过JNI 调用C/C++ 程序

阅读更多

        java是属于比较上层的语言,在大多数情况下,它都可以给开发带来方便和高效率;但是在一些特定的情况下,它可能就没有低级语言那么好用了,所以就需要有能够调用其他低级语言来实现其不擅长的功能.

      JAVA通过JNI来调用C语言的实现,其基本思想是,由java定义接口,由c实现并生成dll文件,再由java通过之前定义的接口调用具体的实现.

     主要步骤有:

  1. 编写.java文件,其中c中的函数要用public native static修饰;
  2. 编译.java文件为.class文件,使用javah生成.h文件;
  3. 按照.h文件中的函数形式在c中实现函数;
  4. 生成.dll文件,拷贝到java工程中.

详细解释:

   第一步骤不多说.

   第二步骤:其命令如,javah -classpath . -jni HelloWorld      --->将当前文件夹中的HelloWorld.class编译成HelloWorld.h;

   第三步骤:将h文件加入到c项目中,并实现.这个也不细述.若不太明白可以参见JNI中另外的一篇文章

   第四步骤:就是将上一步生成的dell文件放在java项目的根路径.

现在就可以测试下了.测试类中在static块中使用System.loadLibrary("hello"); 来加载hello.dell文件.

加载成功后就可以像调用普通的java类一样调用了.

 

接下来给出一个实例:

java代码(为简单起见,不加入任何包):

 

public class HelloWorld {
    public native void displayHelloWorld(String msg);
    
    public native String formatInput(String input);
    
    static {
        System.loadLibrary("hello"); 
    }
 
    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
		helloWorld.displayHelloWorld("中文");
		System.out.println(helloWorld.formatInput("中文您好!"));
    }
}
 生成的h文件:

 

 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    displayHelloWorld
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject, jstring);

/*
 * Class:     HelloWorld
 * Method:    formatInput
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorld_formatInput
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif
 自动生成的可能是 #include <jni.h>,若你的jni.h文件不是在文件头的默认目录中,那么可以改成用引号的方式;

 

两者的区别就在于其查找的方式不一样,引号的方式是在当前目录下查找.
接下来是其实现:
/* Replace "dll.h" with the name of your header */
#include "HelloWorld.h"
#include <stdio.h>
#include <string.h> 
#include <windows.h> 
#include "stdlib.h"

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *env, jclass  obj, jstring jMsg )
{
    /*
    const char *str = (*env)->GetStringUTFChars(env, jMsg, 0);
    */
const char * str = jstringToWindows(env,jMsg);
printf("hello , %s !",str);
return ;
}

JNIEXPORT jstring JNICALL Java_HelloWorld_formatInput
  (JNIEnv *env, jclass  obj, jstring jMsg)
{
    /*nst char *str = (*env)->GetStringUTFChars(env, jMsg, 0);*/
const char * str = jstringToWindows( env, jMsg );

char * Buf_Return;
Buf_Return = (char*)malloc(1024);
sprintf(Buf_Return,"您的輸入是:%s",str);
jstring recv_buf;
recv_buf = WindowsTojstring(env ,Buf_Return);
return recv_buf;
/*
char * str = "hello wang wu!";  
jstring rtn;  
rtn = (*env)->NewStringUTF(env, str);  
return rtn; 
*/
}

char* jstringToWindows( JNIEnv *env, jstring jstr )
{
int length = (*env)->GetStringLength(env,jstr );
const jchar* jcstr = (*env)->GetStringChars(env,jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
    {
return NULL;
    }
(*env)->ReleaseStringChars(env,jstr, jcstr );
rtn[size] = 0;
return rtn;
}


jstring WindowsTojstring( JNIEnv* env, char* str )
{
jstring rtn = 0;
int slen = strlen(str);
unsigned short* buffer = 0;
if( slen == 0 )
rtn = (*env)->NewStringUTF(env,str );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
buffer = malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
rtn = (*env)->NewString( env, (jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
} 
 上面这段代码中有处理过中文的参数,在windows系统下不会出现乱码问题.至于其他系统上就没测试过.
分享到:
评论

相关推荐

    java写的一个使用jni调用c/c++的dll

    本文将深入探讨如何使用Java通过JNI调用C/C++编写的DLL动态链接库。 首先,JNI提供了一个标准的方法,让Java代码可以与本地代码交互,如C/C++。在Java程序中,我们定义`native`方法,这些方法的实现不在Java字节码...

    JNI DEMO:java jni技术 调用 c/c++ 的dll

    在这个DEMO中,我们看到有get()和set()两个方法,这些都是通过JNI调用C/C++实现的。在Java中,这些方法会声明为native,并且没有具体的实现。然后,使用`javah`工具,根据Java类生成相应的C/C++头文件。在C/C++代码...

    jni java调用c/c++

    通过 JNI,Java 程序可以调用 C/C++ 代码,实现 Java 与 native 代码的交互。 在本例中,我们将详细介绍如何使用 JNI 将 Java 代码与 C/C++ 代码集成,生成动态库,并加载到 Java 程序中。 JNI 概述 JNI 提供了一...

    使用JNI进行混合编程:在Java中调用C/C++本地库

    通过以上步骤,我们可以看到,JNI允许Java和C/C++代码无缝集成,实现了跨语言的混合编程。这不仅扩展了Java的功能,还能利用现有的C/C++库,提升程序性能。在实际项目中,我们应当注意内存管理、错误处理和平台兼容...

    Java通过JNI调用C语言函数库的方法.zip

    Java通过JNI(Java Native Interface)调用C语言函数库是一种常见的技术实践,它允许Java程序直接与本地操作系统和硬件交互,提高性能或者利用已有的C/C++代码库。本资料"Java通过JNI调用C语言函数库的方法.zip"提供...

    Java 调用C/C++程序

    最后,Java程序加载这个库,并通过JNI调用这些本地方法。 JNI的调用流程如下: 1. 在Java类中声明native方法,不提供具体实现。 2. 使用`javah`命令生成对应的C/C++头文件。 3. 编写C/C++源代码,实现头文件中的...

    JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单

    通过以上步骤,我们就可以在Java程序中成功地调用C或C++编写的DLL库了。这个过程虽然涉及多个环节,但理解了JNI的工作原理后,你会发现这并不是一项复杂任务。对于那些需要利用C/C++高性能特性的Java应用,JNI是一个...

    JNI实现C/C++与Android/JAVA相互调用

    Android JNI/NDK开发(2)JNI实现C/C++与Android/JAVA相互调用 http://blog.csdn.net/u014702653/article/details/71141423

    ocos2d-x 通过JNI实现c/c++和Android的java层函数互调

    cocos2d-x 通过JNI实现c/c++和Android的java层函数互调, 本文主要实现两个功能: (1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。 (2)通过c++函数调用Android的java层函数,显示一...

    Android项目下使用JNI进行C/C++和Java互相调用

    JNI调用有一定的开销,因此,对于频繁调用或计算密集型的任务,应该尽量减少Java与本地代码之间的交互。此外,正确地管理和释放本地资源(如内存和文件句柄)也是避免内存泄漏的关键。 总结,这个项目展示了在...

    JAVA通过JNI调用C#dll的整个项目工程

    本项目工程提供了完整的Java、C++和C#的示例,可以帮助开发者理解如何在实际项目中实现Java通过JNI调用C# DLL的过程,从而提升应用的性能或实现特定的功能。通过学习和实践这个工程,开发者可以进一步提升跨语言编程...

    java调用C/C++的例子

    总结起来,这些资源可以帮助开发者深入理解和实践Java通过JNI调用C/C++的技术,涵盖了从理论到实战的各个方面。通过学习和使用这些材料,开发者可以有效地将Java应用程序与C/C++库集成,提升程序的性能和功能。

    利用JNI实现Java调用C++库

    利用JNI技术实现Java中调用C++编写的函数库示例程序源码,并附上参考JNI文档。...详情见本人博客:Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)(http://write.blog.csdn.net/postlist)

    JAVA调用C/C++ DLL文件方法

    JAVA 调用 C/C++ 库文件(DLL)可以通过多种方式实现,包括 JNI、JNative、Jawin 和 Jacob 等。每种方式都有其特点和优缺,开发者可以根据实际情况选择合适的方式来实现 JAVA 与 C/C++ 之间的交互。

    JNI开发Java和C/C++互相传递List集合

    JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...

    Java JNI 调用C++ API/dll 示例程序

    完整的展示了Java调用C++ API/dll示例程序. 说明如下: 1. mrSocketAPICInt是准备被java调用的API 2. mrSocketAPIJavaInt是java调用C++ api的中间层 3. mrSocketAPIJavaIntDemo是java程序,展示与C++ api如何对接。...

    java调用C/C++过程

    这篇教程将帮助初学者理解如何通过JNI在Java程序中调用C/C++的函数。 首先,我们需要理解JNI的工作原理。JNI提供了一种桥接机制,使得Java虚拟机(JVM)能够与本地代码(如C/C++)进行通信。这包括定义了Java方法...

    java调用C/C++全过程

    为了弥补这一缺陷,Java引入了JNI(Java Native Interface)技术,允许Java代码直接调用本地C/C++代码,从而实现更深层次的操作系统访问和性能优化。 #### 二、Java调用C/C++的基础概念 在讨论具体过程之前,我们...

    Java通过JNI调用C语言的方法[参考].pdf

    通过JNI,Java开发者可以利用C/C++的高性能特性,实现对硬件的直接操作,调用系统API,或者利用已有的C/C++库,增强Java应用的功能。同时,这也意味着开发过程更加复杂,因为需要处理两种编程语言的集成。

    C++库封装JNI接口-实现java调用c++

    Java程序可以通过JNI调用本地方法,这些本地方法是用其他语言编写的,并通过JNI接口暴露给Java。这个过程涉及到以下几个步骤: 1. **创建本地方法声明**:在Java类中,你需要声明本地方法。这些方法没有具体实现,...

Global site tag (gtag.js) - Google Analytics