⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jni中c++和java的参数传递.txt

📁 java的jni 问题大总结
💻 TXT
📖 第 1 页 / 共 2 页
字号:
{
    jboolean* pba = (env)->GetBooleanArrayElements(ba, 0 );
    jsize len = (env)->GetArrayLength(ba);
    int i=0;
    // change even array elements
    for( i=0; i < len; i+=2 )
    {
        pba[i] = JNI_FALSE;
        printf( "boolean = %s\n", (pba[i]==JNI_TRUE ? "true" : "false") );
    }
    (env)->ReleaseBooleanArrayElements(ba, pba, 0 );
}

/**/////返回一个字符串数组
JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStringArray
(JNIEnv *env, jobject)
{
    jstring      str;
    jobjectArray args = 0;
    jsize        len = 5;
    char*        sa[] = { "Hello,", "world!", "JNI", "is", "fun" };
    int          i=0;
    args = (env)->NewObjectArray(len,(env)->FindClass("java/lang/String"),0);
    for( i=0; i < len; i++ )
    {
        str = (env)->NewStringUTF(sa[i] );
        (env)->SetObjectArrayElement(args, i, str);
    }
    return args;
}

//返回一个结构,这里返回一个硬盘信息的简单结构类型
JNIEXPORT jobject JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStruct
(JNIEnv *env, jobject obj)
{
    /**//* 下面为获取到Java中对应的实例类中的变量*/

    //获取Java中的实例类
    jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");

    //获取类中每一个变量的定义
    //名字
    jfieldID str = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
    //序列号
    jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");


    //给每一个实例的变量付值
    (env)->SetObjectField(obj,str,(env)->NewStringUTF("my name is D:"));
    (env)->SetShortField(obj,ival,10);
    
    return obj;
}

//返回一个结构数组,返回一个硬盘信息的结构数组
JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStructArray
(JNIEnv *env, jobject _obj)
{
    //申明一个object数组 
    jobjectArray args = 0;
    
    //数组大小
    jsize        len = 5;

    //获取object所属类,一般为ava/lang/Object就可以了
    jclass objClass = (env)->FindClass("java/lang/Object");

    //新建object数组
    args = (env)->NewObjectArray(len, objClass, 0);

    /**//* 下面为获取到Java中对应的实例类中的变量*/

    //获取Java中的实例类
    jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");
    
    //获取类中每一个变量的定义
    //名字
    jfieldID str = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
    //序列号
    jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");

    //给每一个实例的变量付值,并且将实例作为一个object,添加到objcet数组中
    for(int  i=0; i < len; i++ )
    {
        //给每一个实例的变量付值
        jstring jstr = WindowsTojstring(env,"我的磁盘名字是 D:");
        //(env)->SetObjectField(_obj,str,(env)->NewStringUTF("my name is D:"));
        (env)->SetObjectField(_obj,str,jstr);
        (env)->SetShortField(_obj,ival,10);

        //添加到objcet数组中
        (env)->SetObjectArrayElement(args, i, _obj);
    }
    //返回object数组
    return args;

 }

//将jstring类型转换成windows类型
char* jstringToWindows( 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类型转换成jstring类型
jstring WindowsTojstring( 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;
}

Java 测试native代码
这没有什么多说的,看代码吧
//主测试程序
    public static void main(String[] args) {
        ChangeMethodFromJni changeJni = new ChangeMethodFromJni();

        //输入常用的数值类型(string int boolean)
        System.out
                .println("------------------输入常用的数值类型(string int boolean)-----------");
        changeJni.displayParms("Hello World!", 100, true);

        //调用一个静态方法
        System.out.println("------------------调用一个静态方法-----------");
        int ret = changeJni.add(12, 20);
        System.out.println("The result is: " + String.valueOf(ret));

        //输入一个数组
        System.out.println("------------------输入一个数组-----------");
        boolean[] blList = new boolean[] { true, false, true };
        changeJni.setArray(blList);

        //返回一个字符串数组
        System.out.println("------------------返回一个字符串数组-----------");
        String[] strList = changeJni.getStringArray();
        for (int i = 0; i < strList.length; i++) {
            System.out.print(strList[i]);
        }
        System.out.println();

        System.out.println("------------------返回一个结构-----------");

        //返回一个结构
        DiskInfo disk = changeJni.getStruct();
        System.out.println("name:" + disk.name);
        System.out.println("Serial:" + disk.serial);

        //返回一个结构数组

        System.out.println("------------------返回一个结构数组 -----------");
        DiskInfo[] diskList = changeJni.getStructArray();
        for (int i = 0; i < diskList.length; i++) {
            System.out.println("name:" + diskList[i].name);
            System.out.println("Serial:" + diskList[i].serial);
        }

    }
注:本程序在VS2003,eclipse (jse5.0) winxp sp2编译通过


posted on 2005-05-02 20:22 sundy 阅读(734) 评论(12)  编辑 收藏 收藏至365Key 所属分类: Java 

 
评论
# re: Jni中C++和Java的参数传递 2005-05-22 14:35 张磊 
请问如果想返回byte[]类型该怎么做  回复    

# re: Jni中C++和Java的参数传递 2005-05-23 08:37 sundy 
因为: 
byte[] jbyteArray 比特型数组 

所以你将byte[] 作为一个jbyteArray数组传递就可以了 
  回复    

# re: Jni中C++和Java的参数传递 2005-09-21 14:46 小影 
请问如果我想把在C++里面计算好的一个二维数组传回给java程序接受,该怎么写代码呢?我找了很多这方面的书和资料,都没有关于传递二维数组的介绍,请您给予指导,多谢啦^_^  回复    

# re: Jni中C++和Java的参数传递 2005-09-21 17:47 sundy 
我没有直接传递过二维数组 
但我想你可以把试一试二维数组转换成为一个Hashmap的数组传出来。 

请参考"如何在Jni中传递出Hashmap的数组?"的一些代码 
  回复    

# re: Jni中C++和Java的参数传递 2005-12-26 16:32 wangjian 
返回一个结构数组时,为什么每个对象的数据都是一样的?即5个Diskinfo的成员值都相同,能不能不相同?  回复    

# re: Jni中C++和Java的参数传递 2005-12-26 16:55 wangjian 
我把5个DiskInfo对象的成员serial分别设置为1、2、3、4、5,可是传递到java后5个对象的serial成员值都是5,为什么这样阿?盼回复,多谢!  回复    

# re: Jni中C++和Java的参数传递 2005-12-27 21:51 sundy 
//给每一个实例的变量付值,并且将实例作为一个object,添加到objcet数组中 
for(int i=0; i < len; i++ ) 
{ 
...... 
//添加到objcet数组中 
(env)->SetObjectArrayElement(args, i, _obj); 
} 

你看看设置的_Obj是不是都是同一个?? 

  回复    

# re: Jni中C++和Java的参数传递 2005-12-28 13:32 wangjian 
如下所示,我就是把你程序中(env)->SetShortField(_obj,ival,10)的参数10换成i,结果每个对象都是对象的serial成员值都是4,请问怎样实现多个不同对象的传递? 
for(int i=0; i < len; i++ ) 
{ 
jstring jstr = WindowsTojstring(env,"我的磁盘名字是D:"); 
(env)->SetObjectField(_obj,str,jstr); 
(env)->SetShortField(_obj,ival,i); 
(env)->SetObjectArrayElement(args, i, _obj); 
} 
  回复    

# re: Jni中C++和Java的参数传递 2005-12-28 15:15 sundy 
应该没有问题的呀, 
SetObjectArrayElement的时候,_obj是不同的吗? 

要不你将for循环改为: 

jstring jstr = WindowsTojstring(env,"我的磁盘名字是C:"); 
(env)->SetObjectField(_obj,str,jstr); 
(env)->SetShortField(_obj,ival,0); 
(env)->SetObjectArrayElement(args, 0, _obj); 

jstring jstr = WindowsTojstring(env,"我的磁盘名字是D:"); 
(env)->SetObjectField(_obj,str,jstr); 
(env)->SetShortField(_obj,ival,1); 
(env)->SetObjectArrayElement(args, 1, _obj); 

看看对吗?   回复    

# re: Jni中C++和Java的参数传递 2005-12-29 20:42 wangjian 
这样作不对,不过我找到正确的方法了,要用构造函数生成新的对象。  回复    

# re: Jni中C++和Java的参数传递 2006-01-17 11:07 luli 
SQLRETURN SQLAllocHandle( SQLSMALLINT HandleType, 
SQLHANDLE InputHandle, 
SQLHANDLE * OutputHandlePtr 
) 
这是odbc api里的一个函数 SQLHANDLE 是一个结构 
c#里的引用方式如下 
[DllImport("ODBC32.dll")] 
private static extern short SQLAllocHandle(short hType, IntPtr inputHandle, out IntPtr outputHandle); 

但我不清楚 SQLHANDLE 结构具体怎么构造的 因此我无法用java类来模拟 

我是菜鸟 望解答 谢过了   回复    

# re: Jni中C++和Java的参数传递 2006-01-17 14:25 luli 
忘了补充 SQLHANDLE InputHandle与SQLHANDLE * OutputHandlePtr 
一个是结构 一个是结构指针 那我是否该如下模拟 

class SQLHANDLE 
{ 
} 
public class test 
{ 
SQLHANDLE a=new SQLHANDLE (); 

public static void main(String args[]) { 
int i=SQLAllocHandle( SQLSMALLINT HandleType, new SQLHANDLE(),a) 
} 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -