简体   繁体   中英

Convert std::string to ndk jstring

I'm trying to create a Java interface to existing C++ code. One of my functions is similar to this one:

JNIEXPORT jstring JNICALL Java_com_testproxy_NativeInterface_serialize
    (JNIEnv* env, jobject obj, along op)
{
     return env -> NewStringUTF(<somestdstring>.c_str());
}

The problem is that in some cases the first element of is '\\0' and because of this, the return value is an empty string. So is there some function to convert char* to jstring which also takes the length of the string as a parameter?

If your string (both if it is a c-style string or an std:: string or an std::wstring) contains a zero as the first character, it means it's null-terminated, and that the content of that string is an empty string.

It is quite important to be aware that the containers we use for string, rely on the fact the last element, terminating the string will be zero.

If we manually manage to change the null terminating zero, to another value (printable or not it doesn't matter), we will expose to a lot of dangers in our code. If a simple strlen would be called on a non-null-terminated string, it will read the contiguous memory until it finds a zero (but it will not represent the length of the string anymore). Given that scenario, you can imagine that violating that rule would most probably compromise the rest of the application.

The reson for this is a bit brutal, but straightforward; look at this implementation of strlen :

std::size_t strlen(const char* start) {
   const char* end = start;
   while(*end++ != 0);
   return end - start - 1;
}

So *end will stop only if it encounters a zero, but since we are supposing it will be removed, we will end up reading some other part of the memory, committing then an obvious mistake in a length calculation.

Back to your case

The reason why this might happen in your case is a bug that inserts a zero in the first position of the string, or the string is just empty, or - more interesting - you are passing a string somewhere, and you return a new empty string instead of the string you intended.

The matter is hardly related to UTF8, as with UTF8 what you may encounter is that the length of the string in glyphs is shorter than the number of bytes needed to store the string itself.

When using UTF8, you need to be aware that the assumption that the number of bytes equals the number of glyphs (which works in ASCII), is not valid anymore, as to print something out of the range 0-127, you will probably need extra bytes.

The case you are showing then is not the responsibility of UTF.

I would suggest investigating the reason why those strings are empty on the C++ side in the first place.

Create a byte array of the expected length, and copy your std::string to this array. Now, you can convert the byte[] to String providing the appropriate character set to the String() constructor.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM