Java-to-CPP Mapping of Strings

  GigaSpaces 5.X

Documentation Home
Quick Start Guide
Release Notes

Previous release

  Search Here
Searching GigaSpaces Platform 5.X Documentation

                                               

Summary: Creating and using a Java String instance; extracting native characters; using strings in printf calls; mixing MFC CString and Java String instances.

Creating a Java String Instance

Usually, you don't need to do anything at all to create a Java string instance. You simply use your C string literal as a method argument or as the right-hand-side in an assignment. The String C++ proxy class does the rest. For example, you don't have to create two Java string instances to put a key/value pair in a Hashtable; rather, this code would be sufficient:

ht.put( "myKey", "myValue" );

As you can see from this example, it is legal to pass a C string literal as an argument to a method that expects an Object argument.
If you need to create a string instance as a local variable you can simply use an assignment statement or a conversion constructor; the two alternatives are entirely equivalent.

java::lang::String temp1 = "my test string";
java::lang::String temp2("my test string");

Assignments also work, just as a Java programmer would expect them to work, with class and instance fields:

MyClass::myField = "test";
myInst.myField = "test";
You can avoid having to always type the name spaces by using a directive:
using namespace java::lang;
String temp1 = "my test string";
String temp2("my test string");

Using a Java String Instance

You can directly use a Java string instance in all places where you would use it in Java. A great deal of attention has been directed to making the Java string class as usable in C++ as possible. For example, you can use a string in output stream operations:

String temp = "test";
cout << temp << endl;

This release of JunC++ion does not support input streams, although this feature is planned for a future release.
You can also use a string in additions:

String temp = "test";
temp = temp + " more!";

As with all proxy instances, you can always compare a string against null to find out whether it is safe to perform an operation on the instance:

String temp = ht.get( "testKey" );
if( temp != null )
   cout << temp << endl;
else
   cout << "testKey not in hashtable!" << endl;

The main usability difference occurs when you need to convert a Java string into a C string or STL string. See the next section for more information.

Extracting Native Characters from a Java String Instance

Extracting native characters from a Java string instance can be problematic. Several factors make this task a complex and non-trivial issue:

  • Java and C/C++ have entirely different string models.
  • A Java string is an object, whereas a C/C++ string is a pointer to a memory location expected to contain characters.
  • It is difficult to determine which of the many different C++ class libraries with different string classes (STL's basic_string, Microsoft's MFC CString, RogueWave's RWCString, and so on) should be supported.
  • There are different character types, char, unsigned char, wchar_t.

As a result of these factors, supporting the complex environment of strings, where one person's string can differ from another's string, is difficult.
This release of JunC++ion supports the basic char and wchar_t types and also includes a couple of utilities that can serve as the basis for user-written utilities. The utilities selected were based on customer demand. In the future, more utilities will be added, depending on customer demand.
The basic API for extracting characters out of a Java string consists of a group of methods that are generated for the string proxy class. These methods can be used to extract the native characters into a pre-allocated buffer.

Using Strings in printf Calls

You need to be very careful when you use C++ classes with the printf() function or one of its cousins (sprintf, vprintf and so on).
Strings are used this way in connection with output streams:

String jstr = "test";cout << jstr << endl;

This code works fine without any additional programmer intervention. The example below suggests how you can pass a Java String instance as an argument to a method that expects a char* argument:

String jstr = "test";
cmjstr temp( jstr );
char * buffer = "This is a \0\0\0\0";strcpy( buffer + 11, temp );

This example is only slightly more complicated than the first example. An instance of the cmjstr utility class is used as an argument instead of the String instance being used directly. The instance of the utility class works because the C++ compiler automatically calls the cmjstr class' const char* conversion operator when it sees that the strcpy function expects a const char* argument.
The printf function is a problem because this function does not make it clear that it expects a char* or const char* argument. The printf function is declared as:

int printf( const char* format, ... );

It is invoked with a format string that contains a mix of both plain characters, as well as placeholders that stand for different kinds of arguments formatted in different ways. For example, %s stands for a string and %d stands for an integer argument. The C++ compiler is not aware of the expected argument types because they really are only encoded in the format string. In other words, the code snippet outlined below won't work.

String jstr = "test";
cmjstr temp( jstr );
printf( "This is a %s", temp );

This code snippet does not work because C++ is not aware that it needs to call the const char* conversion operator to convert the cmjstr instance to characters.
However, it's very easy to make this work using a manual cast:

String jstr = "test";
cmjstr temp( jstr );
printf( "This is a %s\n", (const char*)temp );

While the printf family of functions is the most likely situation where you will encounter this problem, it really is a problem in any function that accepts variable argument lists or void* arguments that are internally cast to char* before being used.

Mixing MFC CString and Java string instances

You can mix MFC CString and Java string instances. A conversion constructor from CString to Java String is generated, which lets you write code like this:

using namespace java::lang;
CString temp = "test";
String jtemp = temp;

In the other direction, you can use either the helper methods that are supplied by the String class and the cmjstr helper class, or write a utility class to do the work for you. This code snippet shows how you might create a CString from a Java string:

using namespace java::lang;
String  jtemp = "test";
CString ctemp;
if( jtemp != null )
{
   cmjstr temp( jtemp );
   ctemp = (const char*)temp;
}

In this example, the cmjstr utility class extracts the characters from the Java instance, after having tested whether there is a string reference with which to work.
You could easily write a utility function that lets you use one line for this entire task:

CString j2cstring( java::lang::String jstr )
{
   CString   result;
   if( jstr != null )
   {
      cmjstr temp( jstr );
      result = (const char*)temp;
   }
   return result;
}
...
String  js = "test";
CString cs = j2cstring( js );

Of course, you can deal in a similar fashion with any other string type that you need. By writing a few lines of utility code, you can make any custom string type almost as usable as the supported types.


Wiki Content Tree


Your Feedback Needed!

We need your help to improve this wiki site. If you have any suggestions or corrections, write to us at techw@gigaspaces.com. Please provide a link to the wiki page you are referring to.

Labels

 
(None)