Category: Proxy usage

Q

How do I create a C++ string from a Java string?

A

This direction is somewhat more complicated than creating a Java string from a C++ string because we get into memory management issues. Essentially, we have to extract the characters from a Java String object and make them available to the C++ developer without leaking the memory which holds them. On top of this basic problem, there is the question of the code page/encoding in which the characters are to be returned.

The String proxy class offers a lof of special support methods to allow you natural usage of String instances in places where C++ expects a C++ string. First of all, there are conversion operators to const char* and to const wchar_t*. You don't have to worry about managing the pointer because the String instance maintains ownership of it. The following snippet illustrates this:

String        temp = myObj.toString();
const char *  pstrTemp = (const char*)temp; 

This looks simple enough, but there's a tricky aspect to it: remember that the String instance manages the returned pointer. That means that the returned pointer's lifecycle is tied to the String instance's lifecycle. To be safe, you always need to ensure that the String instance is still valid when you're using the returned character pointer. Consider the following, incorrectsnippet:

const char *  pstr = NULL;
{ String localStr = "test"; pstr = (const char*)localStr; } // localStr goes out of scope here and invalidates pstr printf( "The string's value is: %s\n", pstr );

Be careful when using temporary String instances and relying on the conversion operator to convert the instance to a character pointer!

Another area of trouble is associated with multiple invocations of the (const char*) conversion operator or one of the to_chars() methods on one String instance. Take the following snippet for example:

String       temp = myObj.toString();
const char * pStr1 = temp.to_chars();
const char * pStr2 = temp.to_chars();


cout << pStr1 << ", " << pStr2 << endl;

Up to the Codemesh runtime version 3.2.9, this would cause a runtime crash because a String instance would have to delete the pStr1 pointer in order to acquire ownership of the pStr2 pointer. This causes the dereferencing of an invalid pointer during the usage of pStr1 in the last line of the snippet. You can avoid this problem by making the String instance a "caching" instance or by only calling the to_chars() method once, for example:

String       temp = myObj.toString();
temp.flags_ |= xmog_base::CACHING;
const char * pStr1 = temp.to_chars(); const char * pStr2 = temp.to_chars(); cout << pStr1 << ", " << pStr2 << endl;

Starting with v3.2.10, a stand-alone String instance is always automatically treated as a "caching" instance which reuses the already retrieved string characters rather than invalidating and reacquiring them. This completely side-steps this particular problem and makes the original, problematic snippet work as expected.


Copyright 2006-2011 by Codemesh, Inc., ALL RIGHTS RESERVED

:
frequently asked questions
home products support customers partners newsroom about us contact us