Difference between revisions of "SDKCppLanguage"
SergeMoutou (Talk | contribs) (→Strings) |
SergeMoutou (Talk | contribs) (→OUString to OString) |
||
Line 248: | Line 248: | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | We see that a rtl namespace has to be used. If not, please replace OUString by ::rtl::OUString. | ||
+ | OUString and OString objects are class type variables, and then the operations that can be performed on O(U)Strings take the form | ||
+ | <pre> | ||
+ | O(U)StringVariable.operation(argumentList) | ||
+ | </pre> | ||
+ | For example, if string1 and string2 are variables of type OUString, then | ||
+ | <pre> | ||
+ | string1.compareTo(string2) | ||
+ | </pre> | ||
+ | can be used to compare both strings. A function like compareTo(), which is part of the O(U)String-class is called a member function. The O(U)String class offers a large number of these member functions, as well as extensions of some well-known operators, like the assignment (=) and the comparison operator (==). These operators and functions are discussed in the following sections. | ||
+ | The OUString and OString methods are similar : we give a complete example which shows any of them : | ||
+ | <pre> | ||
+ | // C++ | ||
+ | #include <stdio.h> | ||
+ | #include <cppuhelper/bootstrap.hxx> | ||
+ | using rtl::OUString; | ||
+ | using rtl::OString; | ||
+ | |||
+ | main( ) { | ||
+ | OUString OUStr1,OUStr2; | ||
+ | OString OStr1, OStr2; | ||
+ | OStr1="Hi every body"; | ||
+ | OStr2="every body"; | ||
+ | OUStr1 = OUString::createFromAscii("Hi every body"); | ||
+ | OUStr2 = OUString::createFromAscii("Hi every body"); | ||
+ | // Returns the length of this string | ||
+ | printf("Length : %d\n",OUStr1.getLength()); // prints out 13 | ||
+ | // Compares two strings | ||
+ | printf("CompareTo : %d\n",OUStr1.compareTo(OUStr2)); // prints out 0 | ||
+ | // Compares two strings | ||
+ | printf("equals : %d\n",OUStr1.equals(OUStr2)); // prints out 1 | ||
+ | if (OUStr1.equals(OUStr2)) printf("OK\n");// prints out OK | ||
+ | // Compares two strings | ||
+ | printf("CompareToAscii : %d\n",OUStr1.compareToAscii(OStr1)); // prints out 0 | ||
+ | // Compares two strings with a maximum count of characters | ||
+ | printf("CompareToAscii : %d\n",OUStr1.compareToAscii(OStr1),10); // prints out 0 | ||
+ | // Perform a comparison of a substring in this string | ||
+ | // is "every body" in position 3 of OUStr1 ? | ||
+ | if (OUStr1.match(OUString::createFromAscii("every body"),3)) | ||
+ | printf("match : OK\n"); //prints out match : OK | ||
+ | // Perform a comparison of a substring in this string | ||
+ | if (OUStr1.matchAsciiL(OStr2,OStr2.getLength(),3)) | ||
+ | printf("matchAsciiL: OK\n"); | ||
+ | // Returns the float value from this string | ||
+ | OUStr2 = OUString::createFromAscii("1.675"); | ||
+ | printf("toFloat : %f\n",OUStr2.toFloat()); // prints out 1.675000 | ||
+ | // Value Of : | ||
+ | OUStr1 = OUStr1.valueOf((float)1.56); | ||
+ | OStr1 = OUStringToOString( OUStr1, RTL_TEXTENCODING_ASCII_US ); | ||
+ | printf( "Value of : %s\n", OStr1.pData->buffer ); | ||
+ | // concat | ||
+ | OUStr2=OUStr2.concat(OUString::createFromAscii(" ...")); | ||
+ | OStr1 = OUStringToOString( OUStr2, RTL_TEXTENCODING_ASCII_US ); | ||
+ | printf( "concat is : %s\n", OStr1.pData->buffer ); | ||
+ | return 0; | ||
+ | } | ||
+ | </pre> | ||
+ | We can also see in this program how the concat method (three last lines) is used. The toFloat() conversion method is not alone : toBoolean(), toChar(), toInt32(), toInt64() , toDouble(), toAsciiLowerCase() and toAsciiUpperCase() exist also. Now we terminate with presenting some other methods (see C++ material) : |
Revision as of 16:03, 13 May 2006
Contents
The UNO C++ Language
The aim of this chapter is to explain peculiarities of the C++ language in the UNO environment and not to provide skills on traditional C++. To put it differently, I want to give here the UNO/C++ background, quite helpful in getting us started. You can find e-Books on C++ here.
Our starting Example : Simple Binaries (Executable)
We want now to start with a SDK example. The purpose of the example presented is to create an executable which interacts with OpenOffice.org. We can imagine two kind of interactions : direct interaction with OpenOffice.org or interaction with one of OOo's shared library. We focus on this second case where the makefile is simpler. The shared library involved is then cppuhelper.uno.so (cppuhelper.uno.dll under Windows). Former case will be examined later. I assume (I know nobody of the SDK team) this example is given to provide the simplest example we can do with the SDK. This is the Lifetime example : see at “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/Lifetime”
Before diving into the examples, you will need to set up your programming environment so you can create UNO programs. What's required depends on what platform you're working. This is shown in the first example with LINUX platform. To check this example you only have to launch the makefile :
cd <OpenOffice.org1.1_SDK> ./setsdkenv_unix cd examples/DevelopersGuide/ProfUNO/Lifetime make make ProfUnoLifetime.runexe
The last command line only launch the binary executable “ProfUnoLifetime” which interact with cpphelper.uno.so (cppuhelper.uno.dll under Windows) even if OpenOffice.org is not running. This example only create and release an object, not more. The constructor and destructor of the object only write out a message. Its little size allow us to give its code here :
// C++ #include <stdio.h> #include <cppuhelper/weak.hxx> class MyOWeakObject : public ::cppu::OWeakObject { public: MyOWeakObject() { fprintf( stdout, "constructed\n" ); } ~MyOWeakObject() { fprintf( stdout, "destructed\n" ); } }; void simple_object_creation_and_destruction() { // create the UNO object com::sun::star::uno::XInterface * p = new MyOWeakObject(); // acquire it, refcount becomes one p->acquire(); fprintf( stdout, "before release\n" ); // release it, refcount drops to zero p->release(); fprintf( stdout, "after release\n" ); } int main( char * argv[] ) { simple_object_creation_and_destruction(); return 0; }
The two methods acquire and release will be encounter later. What they exactly do is not important for the moment. This example recall us how to write a class which inherits from an other class, how to write and call methods and how to instantiate the class. All the listings given below only need to modify this C++ code compile it and run it. You can therefore use the same makefile by possibly changing the name of the source file (tackled in next section).
Types
The UNO types are given in the table below :
- UNO Types
UNO | Type description | Java | C++ | Basic |
char | 16-bit unicode character type | char | sal_Unicode | - |
boolean | boolean type; true and false | boolean | sal_Bool | Boolean |
byte | 8-bit ordinal type | byte | sal_Int8 | Integer |
short | signed 16-bit ordinal type | short | sal_Int16 | Integer |
unsigned short | unsigned 16-bit ordinal type | - | sal_uInt16 | - |
long | signed 32-bit ordinal type | int | sal_Int32 | Long |
unsigned long | unsigned 32-bit type | - | sal_uInt32 | - |
hyper | signed 64-bit ordinal type | long | sal_Int64 | - |
unsigned hyper | unsigned 64-bit ordinal type | - | sal_uInt64 | - |
float | processor dependent float | float | float (IEEE float) | Single |
double | processor dependent double | double | double (IEEE double) | Double |
The UNO's column represents all the types you can find in the specifications files : IDL files. We describe IDL files later (see chapter 10). The C++ column is what we are interested in when we program with this language. If you want to check the different programs given in this chapter, you can use the <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/Lifetime example. Replace the complete object_lifetime.cxx by the listing below (don't forget to save the old file)
// C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> main( ) { sal_Int32 var1; var1 = 34; printf("The var1 value is : %d\n",var1); return 0; }
then launch
make ALL make ProfUnoLifetime.runexe
and it works. Don't forget ./setsdkenv_unix (only one time) on Linux and the corresponding command (setsdkenv_windows.bat) on Windows.
Sequences
A sequence is an abstract view of a set of UNO types with a variable number of elements. As first example, we give a very simple program :
// C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> #include <com/sun/star/uno/Sequence.hxx> using namespace com::sun::star::uno; main( ) { Sequence < sal_Int32 > SetOfInt(5); //var1 = 34; SetOfInt[2]=44; printf("The value is : %d\n",SetOfInt[2]); return 0; }
The important things to notice are as follows :
- the type of each element of the set is put between angular brackets : "<" and ">". In the example above sal_int32 is the type.
- declaration of sequence is done with parenthesis "(" and ")" and the number of elements of the sequence between them. In the example above a sequence of five sal_Int32 elements is declared.
- accessing elements of the sequence is done with "[" and "]" and an index between them. This allows us to say that sequences are referenced like arrays. But they are different in some way, for instance they have not a fixed size.
- We have to include Sequence.hxx file in a program when using sequence. Note that this file is provided with the SDK and this not always the case for all hxx files (some of them have to be reconstructed).
We have to use the correct namespace with adding "using namespace ..." If you don't use this statement you have to write com::sun::star::uno::Sequence instead of Sequence. A Sequence can be created with arbitrary UNO type but not with other types. The object SetOfInt has many methods. We give an example to show any of them :
// C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> #include <com/sun/star/uno/Sequence.hxx> using namespace com::sun::star::uno; main( ) { Sequence < sal_Int32 > SetOfInt(5); sal_Int32 *table; SetOfInt[2]=44; printf("The value is : %d\n",SetOfInt[2]); // Tests whether the sequence has elements, i.e. elements count is greater than zero if (SetOfInt.hasElements()) printf("Set not empty\n"); // Gets a pointer to elements array for reading and writing. If the sequence // has a length of 0, then the returned pointer is undefined table = SetOfInt.getArray(); table[4]=78; printf("The value is : %d\n",SetOfInt[4]); // prints out 78 SetOfInt.realloc(7); printf("New length : %d\n",SetOfInt.getLength()); // prints out 7 return 0; }
The comments explain what is printed out when executing this example. The method realloc is particularly important : it allows the size of set to change.
Let us focus on using sequences in function or as parameter. An example is again more descriptive than a long text :
// C++ // function Sequence < sal_Int32 > initSequence(){ sal_Int32 sourceArray[5]={1,2,3,4,5}; Sequence < sal_Int32 > SeqOfInt(sourceArray,5); return SeqOfInt; } // reference parameter void initSequence2(Sequence < sal_Int32 > &SeqOfInt ) { sal_Int32 sourceArray[4]={1,2,3,4}; Sequence < sal_Int32 > SeqOfInt2(sourceArray,4); SeqOfInt=SeqOfInt2; }
An obvious call could be :
// C++ SetOfInt = initSequence(); printf("New length : %d\n",SetOfInt.getLength()); // prints out 5 initSequence2(SetOfInt); printf("New length : %d\n",SetOfInt.getLength()); // prints out 4
See other material in Developer's Guide (UNO C++ Binding).
Strings
In C, a string is simply an array of characters that always includes a binary zero (often called the null terminator) as its final array element. UNO/C++ API manages strings with two classes one is OUString while the other is OString. The former uses Unicode characters.
- STRING UNO Type
UNO | Type description | Java | C++ | Basic |
string | String of 16-bit unicode characters | Java.lang.string | ::rtl::OUString | String |
But, if you want to use ASCII characters the latter class is for you.
OUString and OString
OUString and OString classes are designed for UNO programmer. Only OString can be used with a standard C printf. To put it differently OString is nearer to the common C ASCII strings (array of characters) than OUString (which is an array of Unicode). But all strings managed by UNO API are OUString. That means, if you want to see something in the console, you have to convert OUString to OString. If you ask something to the user and want to pass it to UNO API, you have to convert OString to OUString. Then if you want to use the console (in general for test) you have to learn first both conversions.
OUString to OString
If OUStr is a OUString object, we give this example for conversion :
// C++ OString o = OUStringToOString( OUStr, RTL_TEXTENCODING_ASCII_US ); printf( "Conversion result : %s\n", o.pData->buffer ); OString to OUString
The inverse conversion is easy too :
// C++ OUString foo; foo = OUString::createFromAscii("Hi every body");
Here is a complete conversion example :
// C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> using namespace rtl; main( ) { OUString OUStr; OUStr = OUString::createFromAscii("Hi every body"); OString OStr = OUStringToOString( OUStr, RTL_TEXTENCODING_ASCII_US ); printf( "OUStr was : %s\n", OStr.pData->buffer ); return 0; }
We see that a rtl namespace has to be used. If not, please replace OUString by ::rtl::OUString. OUString and OString objects are class type variables, and then the operations that can be performed on O(U)Strings take the form
O(U)StringVariable.operation(argumentList)
For example, if string1 and string2 are variables of type OUString, then
string1.compareTo(string2)
can be used to compare both strings. A function like compareTo(), which is part of the O(U)String-class is called a member function. The O(U)String class offers a large number of these member functions, as well as extensions of some well-known operators, like the assignment (=) and the comparison operator (==). These operators and functions are discussed in the following sections. The OUString and OString methods are similar : we give a complete example which shows any of them :
// C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> using rtl::OUString; using rtl::OString; main( ) { OUString OUStr1,OUStr2; OString OStr1, OStr2; OStr1="Hi every body"; OStr2="every body"; OUStr1 = OUString::createFromAscii("Hi every body"); OUStr2 = OUString::createFromAscii("Hi every body"); // Returns the length of this string printf("Length : %d\n",OUStr1.getLength()); // prints out 13 // Compares two strings printf("CompareTo : %d\n",OUStr1.compareTo(OUStr2)); // prints out 0 // Compares two strings printf("equals : %d\n",OUStr1.equals(OUStr2)); // prints out 1 if (OUStr1.equals(OUStr2)) printf("OK\n");// prints out OK // Compares two strings printf("CompareToAscii : %d\n",OUStr1.compareToAscii(OStr1)); // prints out 0 // Compares two strings with a maximum count of characters printf("CompareToAscii : %d\n",OUStr1.compareToAscii(OStr1),10); // prints out 0 // Perform a comparison of a substring in this string // is "every body" in position 3 of OUStr1 ? if (OUStr1.match(OUString::createFromAscii("every body"),3)) printf("match : OK\n"); //prints out match : OK // Perform a comparison of a substring in this string if (OUStr1.matchAsciiL(OStr2,OStr2.getLength(),3)) printf("matchAsciiL: OK\n"); // Returns the float value from this string OUStr2 = OUString::createFromAscii("1.675"); printf("toFloat : %f\n",OUStr2.toFloat()); // prints out 1.675000 // Value Of : OUStr1 = OUStr1.valueOf((float)1.56); OStr1 = OUStringToOString( OUStr1, RTL_TEXTENCODING_ASCII_US ); printf( "Value of : %s\n", OStr1.pData->buffer ); // concat OUStr2=OUStr2.concat(OUString::createFromAscii(" ...")); OStr1 = OUStringToOString( OUStr2, RTL_TEXTENCODING_ASCII_US ); printf( "concat is : %s\n", OStr1.pData->buffer ); return 0; }
We can also see in this program how the concat method (three last lines) is used. The toFloat() conversion method is not alone : toBoolean(), toChar(), toInt32(), toInt64() , toDouble(), toAsciiLowerCase() and toAsciiUpperCase() exist also. Now we terminate with presenting some other methods (see C++ material) :