java 调用 C++ 的dll

6 篇文章 0 订阅

Java  使用jni调用c++函数的步骤:

1.定义java类中的native方法,新建下面一个类

Java代码 

1.       publicclass NativeDemo {  

2.        

3.       publicstaticnativevoid say();  //static的native方法

4.        

5.       publicnativevoid sayHello();  //实例的native方法,两者的处理不一样

6.        

7.       publicstaticint number = 10;  

8.        

9.       int a = 2;  

10.     

11.    publicvoid callThis(){  

12.            System.out.println("c++ call java method");  

13.        }  

14.     

15.    publicstaticvoid main(String[] args) {  

16.            System.loadLibrary("NativeJni");  

17.    //        NativeDemo.sayHello();

18.    new NativeDemo().sayHello();  

19.            say();  

20.        }  

21.    }  

2.进入java命令行


3.在vc++新建一个dll的控制台工程


4.在vc的工程里面导入刚才的那个NativeDemo.h的头文件,然后因为这个头文件需要引用jdk安装目录下的jni.h和jni_mt.h的两个头文件,从jdk的安装目录下的拷贝到工程里面


4.编写NativeDemo.h的头文件定义的两个类的实现(这里需要吧jni.hinclude的时候要改为“”,而不是<>,因为jni.h是在当前工程里面

/*DO NOT EDIT THIS FILE - it is machine generated */

Cpp代码 

1.       #include "jni.h"

2.       /* Header for class NativeDemo */

3.        

4.       #ifndef _Included_NativeDemo

5.       #define _Included_NativeDemo

6.       #ifdef __cplusplus

7.       extern"C" {  

8.       #endif

9.       /*

10.     * Class:     NativeDemo

11.     * Method:    say

12.     * Signature: ()V

13.     */

14.    JNIEXPORT void JNICALL Java_NativeDemo_say  

15.      (JNIEnv *, jclass);  

16.     

17.    /*

18.     * Class:     NativeDemo

19.     * Method:    sayHello

20.     * Signature: ()V

21.     */

22.    JNIEXPORT void JNICALL Java_NativeDemo_sayHello  

23.      (JNIEnv *, jobject);  

24.     

25.    #ifdef __cplusplus

26.    }  

27.    #endif

28.    #endif

c++源文件

#include"NativeDemo.h"

Cpp代码 

1.       #include "jni.h"

2.       #include 

3.       usingnamespace std;  

4.        

5.       JNIEXPORT void JNICALL Java_NativeDemo_say(JNIEnv * env, jclass jclazz)  //static的方法生成的两个参数是JNIEnv * env, jclass jclazz,第二个参数代表java的类的class实例

6.       {  

7.           jclass jclass_native = env->FindClass("NativeDemo"); //查找类的class对象,

8.           jfieldID jfield_numberId = env->GetStaticFieldID(jclass_native,"number", "I"); //获得jclazz类的静态字段number,第三个参数代表静态变量的签名,java每种类型对应到一个签名串

9.           jint jfield_number = env->GetStaticIntField(jclass_native, jfield_numberId);//获得jclazz类的静态变量的值

10.        cout << jfield_number << endl; //打印静态变量的值

11.     

12.    }  

13.     

14.    JNIEXPORT void JNICALL Java_NativeDemo_sayHello(JNIEnv *env, jobject jobj)//实例方法生成的第二个参数是jobject,代表某一个实例

15.    {  

16.        jclass clazz = env->GetObjectClass(jobj); //获得实例jobj的class对象

17.        jfieldID jfield_numberId = env->GetFieldID(clazz,"a", "I"); //获得这个实例的a实例变量

18.        jint jfield_value = env->GetIntField(jobj,jfield_numberId);  //获得这个实例的a实例变量的值

19.        cout << jfield_value << endl;//打印这个实例的a实例变量的值

20.    }  

5.编译这个vc的工程,生成一个dll文件


6.在我的电脑属性里面设置环境变量path增加这个dll的目录,因为java需要从path变量找到这个dll的目录

7.打开eclipse,编写调用的main函数代码

publicclass NativeDemo {

Java代码 

1.       publicstaticnativevoid say();  //static的native方法

2.        

3.       publicnativevoid sayHello();  //实例的native方法,两者的处理不一样

4.        

5.       publicstaticint number = 10;  

6.        

7.       int a = 2;  

8.        

9.       publicvoid callThis(){  

10.        System.out.println("c++ call java method");  

11.    }  

12.     

13.    publicstaticvoid main(String[] args) {  

14.        System.loadLibrary("NativeJni");  

15.          NativeDemo.sayHello();  

16.    new NativeDemo().sayHello();  

17.        say();  

18.    }  

注:可以直接使用  System.load("E://NativeJni.dll"); 

        执行这个main函数,结果如下


在java中需要使用System.loadLibrary("NativeJni");加载vc工程生成的dll文件,这里dll后缀不能加。


 

 

遇到的问题:

1.中文乱码的问题:在Java函数中传入一个中文字符的参数,调用c++那边的函数打印出来的是乱码.

原因是:java 中传入的参数的类型是jstring,c++没有办法处理这种类型的参数,需要转换成合法的windows了性的参数才可以

使用的函数代码如下:

1.  char * JStringToWindows(JNIEnv * pJNIEnv, jstring jstr) 

2.  {  

3.      jsize len = pJNIEnv->GetStringLength(jstr); 

4.  const jchar * jcstr = pJNIEnv->GetStringChars(jstr, NULL); 

5.  int size = 0; 

6.  char * str = (char *)malloc(len * 2 + 1); 

7.  if ((size = WideCharToMultiByte(CP_ACP, 0, LPCWSTR(jcstr), len, str, len * 2 + 1, NULL, NULL)) == 0) 

8.  return NULL;  

9.      pJNIEnv->ReleaseStringChars(jstr, jcstr); 

10.     str[size] = 0; 

11. return str;  

12.

具体的关于中文乱码的问题可以参考下面这篇文章:

http://developer.51cto.com/art/201112/310128.htm


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值