I need to call into a C function using the Android NDK and must return an altered value via a Java String which is passed as a char* parameter to the C function. The problem is that Java strings are passed by value so the changes my C function makes to the string do not reach the calling Java function.
My Java source is as follows, I get sensible output from the values in arg1_j and result_j but as stated, arg3_j is not updated by my C function :
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);
...
My C header file, cptr.h is as follows :
#ifndef CPTR_H_
#define CPTR_H_
#include <stdint.h>
#include <stdbool.h>
int32_t test_cptr(char *, uint32_t, char *);
#endif // ndef CPTR_H_
My C source file cptr.c is as follows :
#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;
}
My Cptr.i file is :
/* 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"
I have tried to use the typemap example in the SWIG examples code (...Examples/Java/typemap/example.i) as follows but without luck. The following example in the same source also didn't work for me, in both cases arg3 was passed as a String and not updated by my C function :
/* 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);
I have also tried carrays.i from various posts on this forum but I am new to Java and Android have not got anything to work. The more explicit you can be in your replies the better from my POV.
Many thanks,
也许您可以使c方法返回修改后的参数,然后以以下形式在Java中调用它:
value = function(value);
Well, I am mistaken ! Very sorry for the noise but the first method from the ..Examples/Java/typemap/example.i that comes with SWIG did in fact work for me. I don't know what I did wrong before but the same cptr.c and cptr.h files as above now work fine with the following changes :
Java source :
import Cptr.Cptr;
...
byte[] arg1_j = "1234567890123456789012345678901234567890123456789012345678901234\0".getBytes();
int arg2_j = 1000;
byte[] arg3_j = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0".getBytes();
Integer result = Cptr.test_cptr(arg1_j, arg2_j, arg3_j);
// convert byte array to hex string using no external libraries
StringBuffer sb = new StringBuffer();
for (byte b : arg3_j) { sb.append(Integer.toHexString( (int) (b & 0xff) )); }
final EditText eText = (EditText) findViewById(R.id.editText1);
eText.setText(sb.toString());
My new Cptr.i file is :
/* File : Cptr.i */
%module Cptr
%{
/* Includes the header in the wrapper code */
#include "cptr.h"
%}
%include "stdint.i"
%include various.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);
}
}
%}
int32_t test_cptr(char* BYTE, uint32_t, char *BYTE);
Hopefully this will help someone else
Thanks for your attention,
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.