java调用C/C++写的dll(转)
Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性。
Java调用C/C++写好的DLL库时,由于基本数据类型不同、使用字节序列可能有差异,所以在参数传递过程中容易出现问题,DLL中可能需要做相应的转换。
使用Java调用DLL动态链接库的方案通常有三种:JNI, Jawin, Jacob. 其JNI(Java Native Interface)是Java语言本身提供的调用本地已编译的函数库的方法,本身具有跨平台性,可以在不同的机器上调用不同的本地库。Jawin和Jacob都是sourceforge.net的开源项目,都是基于JNI技术的依赖Windows的实现,使得在Windows平台下使用COM和DLL的更加方便。
下面,我们来详细介绍一下使用JNI来实现Java与C/C++之间的调用。
一、 JNI简介
JNI是Java Native Interface的缩写。从Java 1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
sun相关文档:http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html
二、 简单步骤
第一步:
编写Java类,用该类将DLL对外提供的函数服务进行声明,其中的Java方法均声明为native,其方法签名可以自定义,不用实现函数体。一个例子如下:DllTest.java
public class DllTest
{
static
{
System.loadLibrary("chat");
}
public static native int connect(int i);
public static native String getstring(String src);
public static void main(String[] args)
{
DllTest dllTest = new DllTest();
System.out.println(dllTest.connect(5));
System.out.println(dllTest.getstring("java send"));
}
}
其中,chat为该动态库的名字,它的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。在这里,定义了两个接口函数,一个是具有int型的入参和返回值的connect函数,一个是具有String字符串对象的入参和返回值的getstring函数。他们都不需要具体的实现。
第二步:
用Javah工具将该Java类生成对应的.h头文件。首先,用javac DllTest.java编译成DllTest.class 文件,然后用 javah DllTest 编译出一个 DllTest.h 文件。这个DllTest.h即是C/C++动态库中的头文件,C/C++程序需要实现它。DllTest.h 的头文件内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class DllTest */
#ifndef _Included_DllTest
#define _Included_DllTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: DllTest
* Method: connect
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_DllTest_connect
(JNIEnv *, jclass, jint);
/*
* Class: DllTest
* Method: getstring
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_DllTest_getstring
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint、jstring是以JNI为中介使JAVA中的数据类型与C/C++中的数据类型之间的一种中间类型。Jint可以直接当做int使用,但是jstring不能和char *等同,需要做一定的转换。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
第三步:
编写C/C++代码实现.h头文件中声明的函数,该C/C++代码中包含jni.h头文件。
int i = 2;
const char *teststr = "c/c++ return";
JNIEXPORT jint JNICALL Java_DllTest_connect
(JNIEnv *, jclass, jint j)
{
i = i + j;
return i;
}
JNIEXPORT jstring JNICALL Java_DllTest_getstring
(JNIEnv * env, jclass, jstring policy)
{
// jstring 转换为char * (utf-8)
const char * s1 = env->GetStringUTFChars(policy, false);
printf("%s/n", s1);
// char * (utf-8) 转换为jstring
jstring js = env->NewStringUTF(teststr);
return js;
}
然后用C/C++的编译工具编译生成char.dll动态库。把这个动态库放到第二步中的DllTest.class所在的文件夹中。
第四步:
用java DllTest 执行调用,你就可以看到输出结果:
7
Java send
c/c++ return
java调用C/C++写的dll(转)的更多相关文章
- JAVA调用C语言写的SO文件
JAVA调用C语言写的SO文件 因为工作需要写一份SO文件,作为手机硬件IC读卡和APK交互的桥梁,也就是中间件,看了网上有说到JNI接口技术实现,这里转载了一个实例 // 用JNI实现 // 实例: ...
- Java调用C/C++实现的DLL动态库——JNI
由于项目的需要,最近研究了java 调用DLL的方法,将如何调用的写于此,便于日后查阅: 采用的方法是JNI:Java Native Interface,简称JNI,是Java平台的一部分,可用于让J ...
- C# 调用C++/MFC写的dll
C#调用C++的非托管类的dll其实很简单基本就是固定的调用格式. dll的编写,首先是打开VS新建一个C++的控制台程序,下一步后选择dll以及空文档即可.然后就是添加一个类添加一个方法.方法排头固 ...
- VS2017写的exe调用Delphi 7写的DLL
公司有个很古老的系统,代码量很大,并且稳定线上运行10几年,这系统是公司的核心,公司收入基本靠它,系统几乎都是Delphi 7写的,要重写是不可能的.因为Delphi 7编译出来的DLL默认的导出符号 ...
- Java调用.dll文件
因为项目的需求,要在JAVA项目中调用Windows的Dll(动态链接库)文件,之前用Jni调用过C写的Dll文件,比较麻烦,这里不多说,网上也有很多这方面的文档.在网上找到一个开源的组件JNativ ...
- java调用dll-JNA
介绍 给大家介绍一个最新的访问本机代码的 Java 框架 —JNA . JNA(Java Native Access) 框架是一个开源的 Java 框架,是 SUN 公司主导开发的,建立在经典的 JN ...
- c++ c# java 调用 c++ 写的dll
1. vs 中新建win32 dll 项目 testdll 添加实现文件 test.cpp #include "stdafx.h" #include <ios ...
- 通过COM组件方式实现java调用C#写的DLL文件
转自这里 最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资 ...
- 通过COM组件方式实现java调用C#写的DLL文件 转
最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资料很多,自 ...
随机推荐
- linux视频学习4(crontab和进程)
1 . crontab定时任务: 任务调度: 系统在某个时间执行的特定的命令. 分类: 1.系统工作.2.个别的用户工作. 设置任务调度文件: /etc/crontab 1.crontab -e : ...
- HDU1492/The number of divisors(约数) about Humble Numbers
题目连接 The number of divisors(约数) about Humble Numbers Time Limit: 2000/1000 MS (Java/Others) Memory L ...
- 内存管理 & 内存优化技巧 浅析
内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户 ...
- SimplePath 使用心得
上图是 用SimplePath 做的 寻路,其中 三个 绿点 是 移动的 目标点,三个红点 是 角色移动,蓝色方块是阻挡物体. 这三个角色 移动 有三种 方式,1 随机移动2 按照 绿色小球点 移动 ...
- angular初始用——简易购物车
<html> <head> <meta charset="utf-8"> <script src="js/angular.js& ...
- Python科学计算学习一 NumPy 快速处理数据
1 创建数组 (1) array(boject, dtype=None, copy=True, order=None, subok=False, ndmin=0) a = array([1, 2, 3 ...
- 使用log4j无法输出日志
前段时间在项目的过程中使用log4j来输出日志,但是在一个项目里我明明已经在src/main/resource目录下创建了log4j.properties.具体配置如下: log4j.rootLogg ...
- android--listview设置高度
android:layout_height="25dp"这么设置根本就没有用. 我们必须要设置android:minHeight="25dp"这样才行.
- Photoshop学习之路
网易云课堂中有的提升课程:http://study.163.com/course/courseMain.htm?courseId=765016&6925ecaa9614a750=Individ ...
- Super Mario
Super Mario Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...