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文件实现.网上资料很多,自 ...
随机推荐
- 取得GridView某行的DataKey
首先绑定DataKeyNames GridView.DataKeyNames = new string[] { "字段名称" }; 取值 string aaa= GridView. ...
- 用 Swift 编写面向协议的网络请求
和我一起参加9 月 1 日 - 9月 2 日在纽约举办的 Swift 社区庆典
- jquery从tr获取td
已知HTML:<tr id="row001"><td>001</td><td>张三</td></tr>JQU ...
- TcpClient 读写流
TcpClient 读写流 TcpClient tcp = new TcpClient(); tcp.Connect(IPAddress.Parse("192.168.1.161" ...
- android 设计模式学习
1:单例模式 //对于创建开销较大的类可使用此方法,保证全局一个实例,在程序运行过程中该类不会因新建额外对象产生开销.示例代码如下:public class Singleton { private s ...
- Light OJ 1008
找规律. 首先令n=sqrt(s),上取整.讨论当n为偶数时,若n*n-s<n则x=n,y=n*n-s+1否则x=-n*n+2*n+s-1,y=n;如果n为奇数,交换x,y即可,对称的. Sam ...
- PHP中require()文件包含的正确用法
以前看一些PHP框架源码的时候,很奇怪在文件包含的时候,会用dirname(__FILE__)来拼凑文件路 径,不知道这样做有什么好处,后来终于发现了其中的缘由. 我们来看一个简单的例子: 有a,b, ...
- Safari WebApp 模拟 原声APP禁止打开新窗口JS代码
if(("standalone" in window.navigator) && window.navigator.standalone) { var noddy, ...
- zf-关于注册码全部错误的解决方法
之所以错误,是因为这里的用户名称是石首市政务服务中心. 在数据库里把这个字段改成 上海卓繁 就可以了 一般都是在 SYS_INFO 这张表里面改
- 51nod 修改数组
修改数组 给出一个整数数组A,你可以将任何一个数修改为任意一个正整数,最终使得整个数组是严格递增的且均为正整数.问最少需要修改几个数? Input 第1行:一个数N表示序列的长度(1 <= N ...