SWIG, can I assign a value to a char** passed from Java to C
I have a C API that looks like this:
int my_function(char** assign_me_a_string);
I basically need the native code to tell me a value. If I do:
char* my_function();
It works fine. I get a String in return that I can use in Java. However I would prefer to use the first approach since all my functions returns an int by default (status value).
I have tried to use various.i and this typemap:
%apply char **STRING_ARRAY { char **assign_me_a_string }
Doing this I get a String[] generated for the Java API. Then I try to use it by:
String[] myStringToAssign = new String[1];
my_function(myStringToAssign);
But this seems to just crash.
So, is there a proper way to assign a value to a Java String from inside the C code? I am not trying to use an array, I just need to be able to dereference the char** and assign it a string in the native code that can then be used as a String object in Java.
Java String is immutable and references are passed by value so the following will not do what you think (pure Java):
// java:
void someFunction(String yourString) {yourString = "bye";}
void test() {
String test = "hi";
someFunction(test);
System.out.println(test); // prints "hi", not "bye"!
}
(For more on this, see for example Passing a String by Reference in Java?). Needless to say you can't do it using JNI either.
Look at section 24.10.5 of SWIG 2.0 docs: it shows how you could do this for char** via a typemap. However the typemap there would have to be modified to check the char* array on exit (the freearg typemap, perhaps) to replace the contents of the String[]. Your function could assume only one item.
Alternately you could wrap your Java String in a class, which will get passed by reference; however you again would have to use a typemap to copy any changes that have been made into the data member.
Probably the easiest is to provide a helper function that swaps the status code and string:
// C/C++ lib: the function you'd like to export but can't:
int my_function(char*& ) {
val = new char[20];
...put stuff in val, don't forget the terminating char...
return status;
}
Create wrapper:
// SWIG .i file: an "adapter" function, Java gives you no choice:
%inline %{
char* my_function(int& err) {
char * val;
err = my_function(val);
return val;
%}
SWIG will take care of copying the char* to the returned String:
// From Java you can then do:
int status;
String result = my_function(status);
System.out.println(result);
不,Java字符串是不可变的,即使通过JNI也不能分配。
链接地址: http://www.djcxy.com/p/20894.html上一篇: 来自PL / SQL过程的Java类文件