Java Jni调用并编写dll详细教程

使用JNI,需要为C\C++生成JAVA调用约定头文件,并对标准windows DLL源码进行适当修改。以下以一个简单的例子演示整个过程。
环境:win7 64位操作系统,JDK1.7 64位,vs2010(安装x64编译支持)。

一,编写native声明的类

 

 代码如下 复制代码
package com.ninecmd;
 
public class MyClass {
static
{
System.loadLibrary("jnidll");
}
public native static void SayHello(String word);
public native static String RepeatWord(String word);
/*public static void main(String[] args)
{
SayHello("hello");
String str = RepeatWord("么么哒");
System.out.println(str);
}
*/
}

“SayHello”,“RepeatWord”为将来dll文件中的函数声明。这个类的作用是生成C\C++头文件
二,生成C\C++头文件
这里需要注意classpath的路径问题。本例中MyClass 类的完整路径为E:\src\com\ninecmd\MyClass.java,类的包名为com.ninecmd,所以classpath应设置为E:\src。

将cmd切换至E:\src。
1、编译MyClass,在同目录生成MyClass.class

 代码如下 复制代码

 
E:\src>javac com\ninecmd\MyClass.java

2、生成头文件(注意classpath路径设置)

 代码如下 复制代码

 
E:\src>javah -classpath E:\src -d com\ninecmd\ -jni com.ninecmd.MyClass

javah参数说明:

 
javah -classpath 类目录 -d 头文件输出目录 -jni 完整类名

此时在E:\src\com\ninecmd目录中生成了com_ninecmd_MyClass.h文件

 代码如下 复制代码
 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ninecmd_MyClass */
 
#ifndef _Included_com_ninecmd_MyClass
#define _Included_com_ninecmd_MyClass
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ninecmd_MyClass
 * Method:    SayHello
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_ninecmd_MyClass_SayHello
  (JNIEnv *, jobject, jstring);
 
/*
 * Class:     com_ninecmd_MyClass
 * Method:    RepeatWord
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ninecmd_MyClass_RepeatWord
  (JNIEnv *, jobject, jstring);
 
#ifdef __cplusplus
}
#endif
#endif

三,编写DLL代码
1、本例编写x64 DLL,打开vs2010,创建一个MFC DLL工程。将平台改为x64.

2、引入头文件,为了顺眼,我把头文件改名为MyClass.h。
3、编写与头文件声明一致的导出函数。
主要代码:

 

 代码如下 复制代码

//将jstring类型转换成windows char*类型
char* jstringToChars( JNIEnv  *env, jstring jstr )
{
    int length = (env)->GetStringLength(jstr );
    const jchar* jcstr = (env)->GetStringChars(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(jstr, jcstr );
    rtn[size] = 0;
    return rtn;
}
 
//将windows char*类型转换成jstring类型
jstring CharsTojstring( JNIEnv* env, char* str )
{
    jstring rtn = 0;
    int slen = strlen(str);
    unsigned short * buffer = 0;
    if( slen == 0 )
        rtn = (env)->NewStringUTF(str );
    else
    {
        int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
        buffer = (unsigned short *)malloc( length*2 + 1 );
        if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
            rtn = (env)->NewString(  (jchar*)buffer, length );
    }
    if( buffer )
        free( buffer );
    return rtn;
}
 
JNIEXPORT void JNICALL Java_com_ninecmd_MyClass_SayHello
    (JNIEnv *env, jobject obj, jstring jstr)
{
    char* str = jstringToChars(env,jstr);
    CString out(str);
    AfxMessageBox((out));
}
 
JNIEXPORT jstring JNICALL Java_com_ninecmd_MyClass_RepeatWord
    (JNIEnv *env, jobject obj, jstring jstr)
{
    return jstr;
}

4、编译发布dll。
四,JNI调用dll
将生成的dll,修改文件名为jnidll.dll,复制到系统System32目录下。将第一步中类代码main函数注释去掉。重新编译类(为保证中文字符串兼容,代码文件需为ANSI编码),并运行测试。
或者用eclipse测试类
测试成功!

时间: 2024-09-20 00:58:15

Java Jni调用并编写dll详细教程的相关文章

java jni调用c函数实例分享(java调用c函数)_java

从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java.C/C++的桥梁--JNI.哈哈!分享一下! 一.简介JNI是Java native interface的简写,可以译作Java原生接口.Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序或者Java无法处理的任务无疑是一个很好的方式. 二.目的:Java代码中调用C/C++代码三.实现:假设我们的Java程序为J2C.java, C程序为J2C.c, Java与C之间的通信函数

linux下 java JNI调用C语言动态链接库

今天花了至少3个小时跑这个java调c的动态链接库的Hello,native world的程序.把所有犯的错误和要点总结一下!1 java 中 c语言函数的声明    public native static void greeting(); //就像是接口声明一样,不过有native!2 编译 javac HelloNative.java ,然后使用 javahjavah HelloNative会自动产生c的头文件HelloNative.h3 生成的头文件 的 第一句子为  #include

用JAVA 设计生成二维码详细教程_java

教你一步一步用 java 设计生成二维码 在物联网的时代,二维码是个很重要的东西了,现在无论什么东西都要搞个二维码标志,唯恐落伍,就差人没有用二维码识别了.也许有一天生分证或者户口本都会用二维码识别了.今天心血来潮,看见别人都为自己的博客添加了二维码,我也想搞一个测试一下. 主要用来实现两点: 1. 生成任意文字的二维码. 2. 在二维码的中间加入图像. 一.准备工作. 准备QR二维码3.0 版本的core包和一张jpg图片. 下载QR二维码包. 首先得下载 zxing.jar 包, 我这里用的

C#调用C++编写dll,参数传递(结构体嵌套联合体)问题

问题描述 typedefstructrealprm{/*realparameter*/longprm_val;/*valueofvariable*/longdec_val;/*numberofplacesofdecimals*/}REALPRM;typedefstructiodbpsd{shortdatano;/*parameternumber*/shorttype;/*upperbyte:type*//*lowerbyte:axis*/union{charcdata;/*bit/bytepar

java-安卓jni调用传入参数问题

问题描述 安卓jni调用传入参数问题 请问一下,一个so库,c是这么调用的 uint8_t* id = NULL; uint32_t length = 0; func(&id, &length); 那么用java jni调用的时候参数怎么写呢,,,小白一个,比较急求大神帮助 传func(String a, Long b)好像并不可以啊 解决方案 在使用so库之前需要使用javah对已定义的本地接口进行编译,在java端传输的参数 实际是你定义本地方法时的参数

有关c# 调用vc++编写的非托管DLL、socket编程等相关知识的讲的比较详细的书籍

问题描述 有关c# 调用vc++编写的非托管DLL.socket编程等相关知识的讲的比较详细的书籍 学习c# 调用vc++编写的非托管DLL.socket编程等相关知识的讲的比较详细的书籍都有哪些?(最好是基于VS2008的) 解决方案 c#调用非托管C++生成的dllc# 调用 C++ 非托管 DllC#调用非托管dll 解决方案二: 这样一个知识点,最好是 Baidu/Google 查找来解决 书上的内容,没有网络上的丰富

求救,java通过JNI调用C++ dll

问题描述 环境:win7+VS2008+eclipse问题:java调用release的dll中的一个函数第三次时出错,前两次都正常,第三次调用时Java代码进入调用dll中该函数的地方编辑器就死掉了,只能强制停止才能结束调试,没有报任何错误,dll也没反馈任何值.vs附加进行方式调试,每次都能正常运行注:在三次调用该函数时,dll的其它函数也被调用,没有出现什么异常.环境:server2003+eclipse同样的代码,dll为release版,第一次调用报错,重新调用就会正常代码无法往外考,

Java通过JNI调用C++程序

JNI是Java Native Interface的缩写,中文为JAVA本地调用.使用JNI可以很方便的用我们的Java程序调用C/C++程序.很多时候,某些功能用Java无法 实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处.但是JNI也有它的缺点,使 用java与本地已编译的代码交互,通常会丧失平台可移植性. 下面是一个JNI例子,调用C++输出"hello world":   第一步:创建Java类,在里面定义一

java 怎么调用DLL文件

问题描述 请问各位大哥,JAVA怎么调用由VFP生成的DLL文件,我查询了好多资料,都是有关JAVA调用由C/C++的DLL文件!但一直都搞不懂怎么调用VFP的DLL文件,麻烦那位大哥能够个详细的介绍!谢谢了!问题补充: MessageBox(0, "This MessageBox is a native Win32 MessageBox", "Caption", 0); 能说明下这几个参数是什么意思吗? 解决方案 传统的做法是用JNI,但是JNI太麻烦了现在有一个