java - 如何在 Android NDK 中通过 JNI 调用 C 函数以 Java 字符串形式返回数据

标签 java c android-ndk java-native-interface swig

我需要使用 Android NDK 调用 C 函数,并且必须通过 Java 字符串返回更改后的值,该字符串作为 char* 参数传递给 C 函数。问题在于 Java 字符串是按值传递的,因此我的 C 函数对字符串所做的更改不会到达调用 Java 函数。

我的 Java 源代码如下,我从 arg1_j 和 result_j 中的值获得了合理的输出,但如上所述,arg3_j 并未由我的 C 函数更新:

import Cptr.Cptr;
...
String arg1_j = new String(new byte[65]);
long arg2_j = 1000;
String arg3_j = new String(new byte[65]);

arg1_j = "1234567890123456789012345678901234567890123456789012345678901234";

Integer result_j = Cptr.test_cptr(arg1_j, arg2_j, arg3_j);

final EditText eText = (EditText) findViewById(R.id.editText1);

eText.setText(arg1_j);
//eText.setText(result_j.toString());
//eText.setText(arg3_j);
...

我的C头文件,cptr.h如下:

#ifndef CPTR_H_
#define CPTR_H_

#include <stdint.h>
#include <stdbool.h>

int32_t test_cptr(char *, uint32_t, char *);

#endif // ndef CPTR_H_

我的C源文件cptr.c如下:

#include "cptr.h"

// The function sets arg3 data and returns arg2 - 1
int32_t test_cptr(char* arg1, uint32_t arg2, char* arg3)
{
    arg3[0] = 'h';
    arg3[1] = 'e';
    arg3[1] = 'l';
    arg3[3] = 'l';
    arg3[4] = 'o';
    arg3[5] = '\0';

    return arg2 - 1;
}

我的 Cptr.i 文件是:

/* File : Cptr.i */
%module Cptr
%{
/* Includes the header in the wrapper code */
#include "cptr.h"
%}

%include "stdint.i"

// Enable the JNI class to load the required native library.
%pragma(java) jniclasscode=%{
static {
try {
java.lang.System.loadLibrary("Cptr"); 
} catch (UnsatisfiedLinkError e) {
java.lang.System.err.println("native code library failed to load.\n" + e);
java.lang.System.exit(1); 
} 
}
%}
/* Parse the header file to generate wrappers */
%include "cptr.h"

我尝试在 SWIG 示例代码 (...Examples/Java/typemap/example.i) 中使用类型映射示例,如下所示,但没有运气。同一源中的以下示例对我来说也不起作用,在这两种情况下,arg3 都是作为字符串传递的,并且没有由我的 C 函数更新:

/* default behaviour is that of input arg, Java cannot return a value in a 
  * string argument, so any changes made by f1(char*) will not be seen in the Java
  * string passed to the f1 function. 
 */
void f1(char *s);

%include various.i

/* use the BYTE argout typemap to get around this. Changes in the string by 
 * f2 can be seen in Java. */
 void f2(char *BYTE);

我还尝试过此论坛上各种帖子中的 crays.i,但我是 Java 新手,Android 没有任何功能。您的回复越明确,我的观点就越好。

非常感谢,

最佳答案

也许你可以让c方法返回修改后的参数,然后在Java中以这样的形式调用它:

value = function(value);

关于java - 如何在 Android NDK 中通过 JNI 调用 C 函数以 Java 字符串形式返回数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24936348/

相关文章:

java - 根据ArrayList中列的顺序生成SQL

java - 在 JavaFX 中的图像上使用 ColorPicker

java - 带有@Scheduled Spring 注释的方法的切入点

java - 从 Java 运行进程,使用 C++ 的输出

java - 在 Eclipse 中方便地将一个类 move 到不同的包中,而不需要 svn

c - C语言中如何知道一个文件是否可以被其他用户读取?

c - 从结构到数组的不完整复制

c - 在C中打印字符串文本不打印

android - 触摸特定图像时放大更近的图片

java - Android Studio中如何生成.so文件和对应的Java接口(interface)