Reputation: 79
As far as I know I can't call method from C++ that will return from Java string array, so only solution for this is loop call method that will return array elements on by one, but how can I store them in C++ array?
In Java I have method:
public static String getData(int index){ return arry[index]; }
and in C++:
char * args[10];
for (int i = 0; i < arrayLength; i ++) {
jmethodID mid = env->GetStaticMethodID(INF.cls_JSox, "getData",(I)Ljava/lang/String;");
jobject result = env->CallStaticObjectMethod(cls, mid, num, i);
const char *nativeString = env->GetStringUTFChars( (jstring) result, 0);
const size_t len = strlen(nativeString);
cout << "copying... \n";
strncpy(args[i], nativeString, len);
env->ReleaseStringUTFChars( (jstring)result, nativeString);
}
but when i
= 1 I'm getting memory violation error in Java. How can I correctly copy data from received strings to the char * args[10]
? The length of every string passed from Java is about 3-5 chars.
Upvotes: 3
Views: 5377
Reputation: 1267
Assuming that the C++ code snippet you posted is complete, you are getting an access violation because you need to allocate args[i]
before copying a value into it - a args[i] = new char[ len + 1 ]
would do.
You can actually call a method from C++ that returns a Java string array, assume your method was:
public static String[] getData() { return array; }
Then on the native side you should be able to do something like:
jmethodID method = env->GetStaticMethodID( cls, "getData", "()[Ljava/lang/String;" );
jarray data = (jarray) env->CallStaticObjectMethod( cls, method );
// assumption: the result of getData() is never null
jsize const length = env->GetArrayLength( data );
// assumption: the String[] is always of length > 0
char** args = new char*[ length ];
for( jsize index(0); index < length; ++index )
{
jstring element = (jstring) env->GetObjectArrayElement( data, index );
// assumption: there are no null strings in the array
char const* nativeString = env->GetStringUTFChars( element, 0 );
jsize const nativeLength = strlen( nativeString );
args[index] = new char[ nativeLength + 1 ];
strncpy( args[index], nativeString, nativeLength );
env->ReleaseStringUTFChars( element, nativeString );
env->DeleteLocalRef( element );
}
I haven't tried to compile the above snippet so there might be an error or two, but it should be an ok starting point. I've left the code using a char* array and native strings, so at some point the code is going to have to call delete[]
on each member of the array and on the array itself. It may end up ultimately simpler using std::vector
and std::string
for memory management depending on how the supplied strings are going to be used.
Upvotes: 6