如何使用JNI调用"主"函数采用字符指针数组? [英] How to use JNI to call a "main" function that takes an array of character pointers?

查看:254
本文介绍了如何使用JNI调用"主"函数采用字符指针数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我有一个C函数

  INT主(INT ARGC,CHAR *的argv [])

和我wrapper.c具有此功能。

  JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv的* ENV,JCLASS类,jint的argc,argv的jcharArray){
    返回主(ARGC,ARGV);
}

和java中我已经这样定义它

 私人原生INT lameMain(INT ARGC,CHAR [] argv的);

但我觉得我做错了什么与argv的参数的......它不是一个字符数组,而是字符指针的数组。

谁能帮助?

当我运行它在我的应用程序崩溃与

  03-20 23:26:23.487:A / libc的(30436):在0xfd90001d(code = 1)致命信号11(SIGSEGV),螺纹30436(包)


解决方案

在Java方面,该数组转换为字符串数组(即的String [] )。它传递这样的。在JNI方面,通过阵列和检索每个字符串的字符。该声明将是这样的:

 私人原生INT lameMain(字符串[] argv的);

和在C:

  JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv的* ENV,JCLASS类,jobjectArray的argv)

有没有必要通过ARGC,因为Java数组存储自己的大小。

这是说,你可能做一些非常错误的。典型的Andr​​oid程序不与启动主和不带命令行参数 - 他们的活动来代替。 AC 的main()函数是一个程序的起点,但因为你是从Java端调用它,它不是在节目的第一件事。

编辑:好吧,但我还是觉得你在多个计数这样做不对。我把它的EN codeR需要一个文件 - 对不对?所以,你保存从内存波到一个文件中的只是为了再次读取的?这是跛脚(双关语意)。

另外,你真的需要通过从Java端任意大小的数组?如果你知道在设计时参数的个数,和它的小(比如,2),这是非常非常容易,只是传递两个的jstring 秒。

总之,在这里不用数组的东西。这里假设你的JNI库的来源是C ++,不C.对于C,JNI的功能invokation会略有不同,你必须使用/ malloc的的免费,而不是新/删除。

  JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv的* ENV,JCLASS类,jobjectArray jargv)
{// jargv是Java字符串的Java数组
    INT ARGC = env-> GetArrayLength(jargv);
    的typedef的char * PChar类型;
    PChar类型* argv的=新PChar类型[ARGC]
    INT I;
    对于(i = 0; I< ARGC,我++)
    {
        JS的jstring = env-> GetObjectArrayElement(jargv,I); // Java字符串
        为const char * PJC = env-> GetStringUTFChars(JS); //一个指向一个Java管理字符缓冲区
        为size_t jslen = strlen的(PJC);
        的argv [i] =新的char [jslen + 1]; //额外字符为终止空
        的strcpy(argv的[I],PJC); //复制到*我们*缓冲区。我们可以省略,但恕我直言,这是清洁。另外,const正确性。
        env-> ReleaseStringUTFChars(JS,PJC);
    }    //调用主
    主(ARGC,ARGV);    //现在释放数组
    对于(i = 0; I< ARGC,我++)
        删除[]的argv [I]
    删除[] argv的;
}

hi i have an c function

int main(int argc, char *argv[])

and my wrapper.c has this function

JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv *env, jclass class, jint argc, jcharArray argv) {
    return main(argc, argv);
}

and in java i've defined it like this

private native int lameMain(int argc, char[] argv);

but i think i'm doing something wrong with the argv-argument... it's not an char-array, but a array of char-pointers.

can anyone help?

when i run it my app crashes with

03-20 23:26:23.487: A/libc(30436): Fatal signal 11 (SIGSEGV) at 0xfd90001d (code=1), thread 30436 (package)

解决方案

On the Java side, convert the array to an array of strings (i. e. String[]). Pass it like that. On the JNI side, go through the array and retrieve the characters of each string. The declarations would go like this:

private native int lameMain(String[] argv);

And in C:

JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv *env, jclass class,  jobjectArray argv )

There's no need to pass argc, because Java arrays store their own size.

That said, you're probably doing something very wrong. Typical Android programs don't start with main and don't take command line arguments - they have activities instead. A C main() function is a starting point of a program, but since you're calling it from the Java side, it's not the first thing in the program.

EDIT: Okay, but I still think you're doing this wrong on more than one count. I take it, the encoder takes a file - right? So you save the wave from memory into a file just to be read again? That's lame (pun intended).

Also, do you really need to pass an arbitrary sized array from the Java side? If you know the number of arguments at design time, and it's small (say, two), it's much, much easier to just pass two jstrings.

Anyway, here goes the array stuff. This assumes the sources of your JNI library are C++, not C. For C, the invokation of JNI functions would be slightly different, and you'd have to use malloc/free instead of new/delete.

JNIEXPORT jint JNICALL Java_package_Class_lameMain(JNIEnv *env, jclass class,  jobjectArray jargv)
{    //jargv is a Java array of Java strings
    int argc = env->GetArrayLength(jargv);
    typedef char *pchar;
    pchar *argv = new pchar[argc];
    int i;
    for(i=0; i<argc; i++)
    {
        jstring js = env->GetObjectArrayElement(jargv, i); //A Java string
        const char *pjc = env->GetStringUTFChars(js); //A pointer to a Java-managed char buffer
        size_t jslen = strlen(pjc);
        argv[i] = new char[jslen+1]; //Extra char for the terminating null
        strcpy(argv[i], pjc); //Copy to *our* buffer. We could omit that, but IMHO this is cleaner. Also, const correctness.
        env->ReleaseStringUTFChars(js, pjc);
    }

    //Call main
    main(argc, argv);

    //Now free the array
    for(i=0;i<argc;i++)
        delete [] argv[i];
    delete [] argv;   
}

这篇关于如何使用JNI调用&QUOT;主&QUOT;函数采用字符指针数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆