Java中利用JNI调用c++生成的DLL

一、编写Java

package test;

public class TestJNI

{
    public native int add(int a,int b);
    public native String upperCase(String str);
    static
    {
       System.loadLibrary("JniDll");
    }
    public static void main(String[] args)
    {
       TestJNI test = new TestJNI();
       int a=100, b=20, result;
       result = test.add(a, b);
  
       System.out.println("sum:" + result);
       String str1, str2,str3;

       str1 = "abcDEFhijk";
       str3 = "eahis";

       str2=test.upperCase(str1);
       System.out.println(str2);
    }

}

二、编译完成后生成TestJNI.class

三、执行javah TestJNI命令,生成.h文件

Cmd切换到src目录cd E:\eclipse\workspace\JNI\src

javah -classpath E:\eclipse\workspace\JNI\bin-d d:/ -jni test.TestJNI

产生test_TestJNI.h文件到d:\

在java中,提供了javah这个命令来生成本地方法的头文件。使用命令如下:

javah-classpath A -d B -jni C

其中,A是你的.class文件的路径,这样java就可以搜索到这个.class文件。B是将要生成的头文件的存放目录,可以根据需要指定。C是java类名,在这个例子中就是com.jni.test.Example。然后就可以在B目录下看到生成的头文件了。

6、打开vc++,新建一个DLL程序,选中Empty project,test_TestJNI.h复制到此工程目录下,并添加到工程中,JniDll.cpp文件,包含jdk相应文件,(工具-选项-目录)Tools-->Options-->vc++ Directories-->include files:D:\ProgramFiles(x86)\Java\jdk1.7.0_02\include 

D:\ProgramFiles(x86)\Java\jdk1.7.0_02\include\win32

注意:cpp中的方法名和.h中的方法名,必须完全一致

#include <iostream>
#include <string>
#include <windows.h>
#include "test_TestJNI.h"
using namespace std;

JNIEXPORT jint JNICALL Java_test_TestJNI_add(JNIEnv *env,jobject,jint a,jint b)
{
    int result = (int)(a +b);
    return (jint)result;
}

jstring str2jstring(JNIEnv *env,const char* pat)

{    
    //定义java String类strClass
    jclass strClass = (env)->FindClass("Ljava/lang/String;");
    //获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
    jmethodID ctorID = (env)->GetMethodID(strClass,"<init>","([BLjava/lang/String;)V");
    //建立byte数组
    jbyteArray bytes = (env)->NewByteArray(strlen(pat));
    //将char*转换为byte数组
    (env)->SetByteArrayRegion(bytes, 0,strlen(pat), (jbyte*)pat);
    // 设置String, 保存语言类型,用于byte数组转换至String时的参数
    jstring encoding = (env)->NewStringUTF("GB2312");
    //将byte数组转换为java String,并输出
    return (jstring)(env)->NewObject(strClass,ctorID,bytes,encoding);
}    


string jstring2str(JNIEnv*env,jstring jstr)

{       
    char*  rtn   =  NULL;
    jclass  clsstring   =  env->FindClass("java/lang/String");
    jstring  strencode   =  env->NewStringUTF("GB2312");
    jmethodID  mid   =  env->GetMethodID(clsstring,  "getBytes",  "(Ljava/lang/String;)[B");
    jbyteArray  barr=   (jbyteArray)env->CallObjectMethod(jstr,mid,strencode);
    jsize  alen   =  env->GetArrayLength(barr);
    jbyte*  ba   =  env->GetByteArrayElements(barr,JNI_FALSE);
    if(alen   >   0)     

    {           
        rtn   =   (char*)malloc(alen+1); 
        memcpy(rtn,ba,alen);         
        rtn[alen]=0;      
    } 
    env->ReleaseByteArrayElements(barr,ba,0);
    string stemp(rtn);
    free(rtn);   
    return  stemp;  
}

 JNIEXPORT jstring JNICALL Java_test_TestJNI_upperCase(JNIEnv *env,jobject,jstring str)

{
    string strUpper;
    strUpper =jstring2str(env,str);
    strUpper = (string)strupr((char*)strUpper.c_str());
    jstring strResult =str2jstring(env,strUpper.c_str());
    return strResult;
}
 

用组件模式release,不可用debug模式,编译和生成dll,复制dllsrc目录即可。



JAVA运行结果:

sum:120
ABCDEFHIJK


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值