java c/cpp互相调用实例(姊妹篇之一)
----------java调用c/cpp
(之二c/cpp调用java)
此文章纯粹实例操作,关于jni已经有不少人不少文章讲的很清楚了,所以就不罗列理论了。
看了kimmking的
JNI技术实践小结,又读了danlley的
Java JNI 编程进阶,这些文章中都是自己调用自己,方法很java化,而对于真正的调用dll还是不理解,心中一直存在问题:现在系统中已经有的dll我该如何去调用?如果一个大工程里需要cpp和java一起开发,cpp给出接口、SDK,我该如何处理?
带着这些疑问我决定从cpp到java的jni调用这个全过程亲自动手操作一下。
完成此示例需要下列工具/环境:
1、java环境(废话谁都知道)
2、编译c/cpp的工具。推荐用vs/vc++,我用的是vs2008
一 先制作一个系统中有的DLL文件(cpp给出的sdk接口)
既然是测试我们就把我们这个dll叫做testDll吧,为了简单其间,我只写一个add方法,就是简单的2个数字相加,对于真正的开发中我们肯定会遇到其他类型,java到c/cpp中类型需要转换,具体类型转换对应关系g一下就能得到,我也不在列举。c/cpp中一个class一般包含2个文件,一个头文件定义(*.h),一个文件主体(*.c/*.cpp)。啰嗦了这么多还是直接动手吧,先在vs2008中建立一个工程(当然你也可以直接编写不用这些IDE工具,gcc g++的命令自己g。下同,不在注释不在废话),选取win32工程
键入工程名字testDll,点击next选取DLL,然后点击完成
打开我们的testdll.cpp,添加进我们的add方法
int add(int a,int b){
return a+b;
}
注意到文件列表里并没有testDll.h,因为我们要给出调用者一个接口,如果不给头文件,人家就没办法调用,所以我们就必须添加一个头文件testDll.h。
#ifdef TEST_DLL
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
TEST_API int add(int,int);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
在这个头文件中我们把我们的add方法给定义了进去。注意到testdll.cpp中#include "stdafx.h",所以我们就把这个testDll.h include进stdafx.h里面。
按道理说我们的这个dll已经完成了,但是一般c/cpp给接口SDK的时候大都给.h和.lib,为了一步生成dll和lib,我们添加进一个testDll.def,有了这个文件就可以一步生成dll和lib。在source file里右键add new item ,选择Module-Definition File
键入testDll,OK了,我们可以直接build了。生成testDll.dll和testDll.lib。
把testDll.dll扔到system32目录里等待我们高大威猛的java jni调用。
二 JNI
2.1 编写java文件
为了显示我们的与众相同,我们就把我们的这个java文件命名为Demo.java顺便直接带上包名
,因为我们知道人家给我们的接口里有个add方法,所以我们就直接来个调用吧。
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
}
demo.java代码暂时如此,我们把将要生成的jni的dll叫做jniDll,有童鞋讲,我不想用你这个烂名字jniDll多俗啊,没关系,你可以换,随你换,生成文件后你再换也可以,现在换也可以。
2.2 生成.h头文件
javah命令,不多讲。生成的文件com_testJni_testDemo_Demo.h这个文件的命名规则我就不多讲了,一目了然。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_testJni_testDemo_Demo */
#ifndef _Included_com_testJni_testDemo_Demo
#define _Included_com_testJni_testDemo_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testJni_testDemo_Demo
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
2.3 用c/cpp实现这个头文件
c/cpp中已经实现了这个add方法,我们只需要调用就可以啦。所以直接vs2008中建立一个dll工程,工程名我们就叫jniDll,具体过程不再多讲,方法同上面testDll的建立一样。在这个工程里kimmking把需要引用的包、文件等已经讲的很清楚了。打开jniDll.cpp,添加下面代码
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *env,jclass jobject,jint a,jint b){
return add(a,b);
}
因为int对应的类型就刚好是jint,所以就不需要转换,其他需要转换的类型自己g对应关系转换,注意释放。
这个工程里我们还需要打开 stdafx.h添加
#include <jni.h>
#include "testDll.h"
#include "com_testJni_testDemo_Demo.h"
在编译这个jniDll工程的时候需要引入testDll.h,com_testJni_testDemo_Demo.h,另外添加testDll.lib这个依赖。
好了做好这些后,build下,生成了我们期待已久的jniDll.dll,把这个dll同样扔到system32下。
三 测试
本人特懒,不想写多余的class,所以直接修改Demo.java 这也是刚才为什么讲暂时如此的原因
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
public static void main(String[] args) {
System.out.println(add(7,2));
}
}
四 最后补充
如果系统已经加载过c/cpp的dll,我们就不用再System.loadLibrary("testDll")了,加载一遍就可以了,因为我们刚才写的testDll系统没有加载,所以我就加载了一下。对于多个dll可以写多个System.loadLibrary去加载,修改static{}里面的内容不需要重新生成dll,除非你多加了一个调用方法,如果你看清楚规则,就不用javah命令就可以直接编写头文件,用javah太麻烦了。
【参考文章】
http://www.iteye.com/topic/304594 JNI技术实践小结--原理分析和详细步骤截图说明
http://www.iteye.com/topic/295776?page=1 Java JNI 编程进阶
- 大小: 46.6 KB
- 大小: 25.8 KB
- 大小: 57.9 KB
- 大小: 55.8 KB
分享到:
- 2009-08-31 09:52
- 浏览 2529
- 评论(6)
- 论坛回复 / 浏览 (6 / 35926)
- 查看更多
相关推荐
总结来说,这个“简单JNI实例调用第三方.so库”的例子展示了如何在Java应用程序中通过JNI调用C/C++代码。这个过程包括:定义Java的native方法、使用javah生成C/C++头文件、编写C/C++实现、编译生成.so库以及在Java...
JNI 调用实例(Java、C++ 互相调用实例) 本文旨在介绍 Java 和 C++ 之间的互相调用实例,通过 JNI(Java Native Interface)技术,实现 Java 调用 C++ 和 C++ 调用 Java 的操作。下面将对标题、描述、标签和部分...
我们将以"android调用JNI实例"为例,一步步解释这个过程。 首先,我们需要准备开发环境。安装Android NDK是必不可少的步骤,NDK(Native Development Kit)是一组工具,开发者可以使用它来编写用C和C++编写的本地...
在这个“GMSSL的java调用(JNI库和调用实例).zip”压缩包中,我们主要探讨如何在Java环境中通过JNI(Java Native Interface)来调用GMSSL库,以便利用这些国密算法进行数据加解密和哈希运算。 首先,我们需要了解...
总之,JNI实例“Java调用DLL c++调用Java”是一个实用的学习资源,它详细解释了如何利用JNI进行Java与C++的交互,无论是将本地库引入Java程序还是将Java功能嵌入C++应用。通过实践这些例子,开发者能够深入理解JNI的...
本实例是基于Eclipse的JNI应用,已经过测试,能够帮助开发者直观地理解JNI的调用流程。 首先,我们来详细了解一下JNI的基本概念。JNI提供了一种方式,让Java代码可以调用本地(非Java)代码,也可以让本地代码调用...
在这个"第一个JNI实例学习"中,我们将探讨如何创建并运行一个基本的JNI程序。 首先,我们需要理解JNI的核心概念。JNI提供了一套接口,让Java代码能够声明本地方法,这些方法在运行时由本地(非Java)代码实现。本地...
总结来说,这个实例展示了Java通过JNI调用C++本地方法的基本流程,包括Java端的声明、JNI头文件的生成、C++的实现、动态链接库的编译以及最终的调用。虽然这个实例没有涉及复杂的类型转换,但在实际应用中,根据数据...
`jobject`参数代表Java对象实例,但由于我们是在静态方法中,所以通常用作注释。`Java_com_example_ndkdemo3_MainActivity_stringFromJNI`是Java本地方法的签名,由Java类全名、方法名和参数类型组成。最后,我们...
这篇博客文章“JNI实例”可能详细介绍了如何在实际项目中应用JNI。 在Java中,JNI提供了接口让Java代码能够调用本地(native)代码,本地代码可以是用C、C++或者其他支持的语言编写。这个过程包括以下几个关键步骤...
在本实例中,我们将深入探讨如何使用纯C语言通过JNI调用Java对象的方法。这个例子特别适合那些需要利用C/C++的高效性能,同时又需要与Java应用程序集成的开发者。 首先,我们需要理解JNI的基本概念。JNI提供了一套...
在这个"Java jni调用c实例"中,我们将深入探讨如何通过JNI在Java应用程序中调用C语言编写的函数。 首先,我们需要了解JNI的基本结构。一个典型的JNI程序包括Java源代码、C/C++源代码以及对应的头文件。Java源代码中...
《JNI调用C++的应用实例》 JNI,全称Java Native Interface,是Java平台中用于实现Java代码与其他语言(如C/C++)交互的关键技术。自Java 1.1起,JNI已成为Java平台的标准组成部分,它允许Java应用程序利用本地代码...
本实例将深入探讨如何在Android应用中使用JNI。 1. **JNI简介** JNI是Java平台提供的一种接口,它使得Java代码可以调用本地(非Java)代码,同时也允许本地代码调用Java方法。这种混合编程模式为开发者提供了更大...
本实例将深入浅出地介绍如何通过JNI调用第三方DLL库,并以最简单的整型参数传递为例,帮助初学者快速理解JNI的工作原理。 首先,我们需要创建一个Java类,声明native方法。在Java中,我们使用`native`关键字来标记...
在本实例中,我们将深入探讨如何使用JNI调用第三方DLL(动态链接库)文件,这是在Java应用程序中利用C++或C代码能力的常见场景。这个实例是在Visual Studio 2010环境下构建的,但请注意,其他环境可能需要不同的配置...
本实例提供了一个使用JNI调用C++ DLL(动态链接库)的示例,对于学习和理解JNI的工作原理及其应用非常有帮助。 首先,我们来了解JNI的基本概念。JNI包含了一组头文件和库,它们定义了Java虚拟机(JVM)与本地代码...
这个例子"android studio中JNI调用第三方库例子"是基于谷歌官方提供的"hello-libs"示例项目,旨在帮助开发者了解如何在Android Studio中使用JNI来调用预编译的第三方动态链接库(.so文件)。 首先,我们需要理解JNI...
`jobject`参数是Java对象的引用,通常是你调用JNI函数的Java类实例。 为了从Java层调用这个C++函数,我们需要生成JNI接口。SWIG(Simplified Wrapper and Interface Generator)是一个工具,可以帮助我们自动生成...