FR/Documentation/LanguageCpp

From Apache OpenOffice Wiki
Jump to: navigation, search

Le but de ce chapitre est d'expliquer les particularités du langage C++ dans un environnement UNO et pas d'expliquer ce qu'est le C++.

Le langage C++ et UNO

Le but de ce chapitre est d'expliquer les particularités du langage C++ dans l'environnement UNO et non de fournir des connaissances en C++ traditionnel. Pour dire les choses autrement je veux donner les fondement de C++ et UNO pour nous permettre de commencer.

L'apprentissage de C++ peut se faire à l'aide de livres électroniques malheuresement en anglais here.

Notre exemple de départ : un binaire exécutable

Nous allons partir d'un exemple du SDK. L'objectif de l'exemple présenté est de créer un exécutable qui interragit avec OpenOffice.org. On peut imaginer deux types d'interactions : une interaction directe avec OpenOffice.org ou une interaction avec les librairies partagées d'OpenOffice. Nous nous intéresserons au second cas pour lequel le fichier makefile est plus simple. La librairie dynamique partagée est cppuhelper.uno.so (cppuhelper.uno.dll sous Windows). Le premier cas sera examiné plus tard.

Je suppose (je ne connais personne de l'équipe de développement du SDK) que cet exemple est fourni pour montrer le programme le plus simple qui peut être réalisé avec le SDK. C'est l'exemple Lifetime : voir dans le répertoire “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/Lifetime”

Avant de lancer l'exemple, il vous faudra positionner votre environnement pour pouvoir créer un programme UNO. Ce qui est requis comme information dépend de la plateforme que vous utilisez. Nous montrons ci-dessous comment les choses se passent sous LINUX. Pour tester cet exemple nous avons simplement à lancer le makefile : Template:Documentation/Linux

La dernière ligne de commande lance seulement le binaire exécutable “ProfUnoLifetime” qui interagit avec cpphelper.uno.so (cppuhelper.uno.dll sous Windows) même si OpenOffice.org n'est pas lancé. Cet exemple crée et dispose un objet UNO sans plus avec des constructeurs et destructeurs qui affichent un message correspondant. Sa taille étant réduite, nous donnons son code source maintenant :

// Listing 1 Premier Exemple (du SDK)
// 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;
}

Les deux méthodes acquire et release seront rencontrées et détaillées plus tard. Ce qu'elles font exactement n'est pas important non plus pour le moment. Cet exemple nous rappelle aussi comment on écrit des classes qui h"ritent d'autres classes et comment instancier la classe.

Tous les listings de ce chapitre pourront être réalisés (et compilés) uniquement en changeant le code source de cet exemple sans en changer de nom, ce qui permet de garder le même makefile.


Types

Les types UNO sont répertoriés dans le tableau ci-dessous :

Types UNO
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

Les colonnes UNO représentent tous les types que nous pouvons trouver dans les fichiers IDL. Nous décrirons les fichiers IDL plus tard (voir chapitre 10). Les colonnes C++ sont celles qui nous intéressent le plus, quand nous programmons en C++. Si vous voulez tester les différents programmes donnés vous pouvez aller dans le répertoire exemple du SDK : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding et remplacer alors complètement le fichier initial ”office_connect.cxx” par le programme ci dessous :

//Listing 2 Petit programme d'exemple
// C++
#include <stdio.h>
#include <cppuhelper/bootstrap.hxx>
 
main( ) {
	sal_Int32 var1;
	var1 = 34;
	printf("The var1 value is : %d\n",var1);
   	return 0;
}

ensuite lancer un make :

make ALL
make office_connect.run

et cela fonctionne. Ne pas oublier: ./setsdkenv_unix sur Linux.

Sequences

Une séquence est une vue abstraite de la notion d'ensemble. Comme exemple, nous donnons

//Listing 3 Utilisation des séquences
// 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;
}

Nous pouvons déduire 5 règles d'utilisation des séquences :

  • le type de chaque élément est défini entre : “<“ et “>”
  • la déclaration de séquence est faite comme d'habitude avec un constructeur nécessitant un paramètre optionnel entre parenthèses qui spécifie la taille de la séquence
  • l'accès à chaque éléments de la séquence est faite comme avec un tableau à l'aide de crochets et un index entre ceux-ci
  • Une directive d'inclusion est nécessaire ; rien ne se fera sans Sequence.hxx. Prenez bien note que pour cette fois le fichier correspondant est fourni avec le SDK mais comme j'ai déjà eu l'occasion de l'écrire, ce ne sera pas toujours le cas.
  • Il faut gérer l'espace de nommage correspondant : “using namespace ...” Si vous ne le faites pas il vous faudra écrire com::sun::star::uno::Sequence au lieu de Sequence.

Nous donnons maintenant un exemple sur une séquence d'entiers.

//Listing 4 Un autre exemple de séquence
// 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]); // print out 78
	SetOfInt.realloc(7);
	printf("New length : %d\n",SetOfInt.getLength()); // print out 7
	return 0;
}

Les commentaires affichés expliquent ce qui résulte du programme. La méthode realloc est particulièrement importante : elle permet de changer la taille de l'ensemble en cours de route.

Portons notre attention maintenant sur l'utilisation des séquences comme paramètre de retour d'une fonction ou comme paramètre. Un exemple est encore plus parlant qu'un long discours :

// Listing 5 Sequence et Parametres 
// 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;
}

Un appel trivial pourrait être :

// Listing 6 Sequence and Parameters (following) 
// 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

On ne peut pas quitter cette section sans ajouter que les opérateurs == et != sont disponibles avec les séquences. A noter aussi que « toUnoSequence », « getCppuSequenceType » et « getCharSequenceCppuType() » sont des fonctions membres de la classe séquence.

Passer une séquence dans une fonction comme paramètre par valeur est, comme un vecteur (de la librairie standard C++ STL) quelquechose d'inefficace parcequ'il faut recopier toute la séquence dans la pile. Il est donc largement préférable d'utiliser une référence constante comme montré ci-dessous :

// Listing 7 La méthode de référence constante
//C++
#include <iostream>
#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/uno/Sequence.hxx>
using namespace com::sun::star::uno;
using namespace std;
 
// Passer une Sequence par valeur en utilisant la référence constante
void avoidCopy(const Sequence< double > &ConstRef){
	// ConstRef[2]=6.7; would fail here
	for(int i=0;i<ConstRef.getLength();i++)
           cout<<ConstRef[i]<<" ";
	cout<<endl;
 
}
 
main( ) {
    Sequence < double > demo(5);
    demo[0]=1.1;
    demo[1]=2.1;
    demo[2]=3.1;
    demo[3]=4.1;
    demo[4]=5.1;
    avoidCopy(demo);
    return 0;
}

Pour aller plus loin aller consulter le Developer's Guide (UNO C++ Binding).

Chaîne de caractères

Nous redonnons la représentation des différentes chaînes de caractère.

Personal tools