| Ravi Welcome About Ravi Download Documentation Introduction Ravi-News Installation Starting Ravi ravi-1top-level Le module trace Premiers pas avec Ravi Les ports d'E/S load, require, modules Système d'interruptions Scheme compiler Generating C++ modules Le type "C-object" Le module modxdraw bug report ![]() ![]() |
Ce repertoire contient un exemple d'un programme C++ qui peut être chargé
comme module dans Ravi. Cet exemple a été proposé par Vincent Colin,
les sources originelles sont dans ~colin/Exemple
Premier exemple Point.hh Point.cc modPoint.phDeuxième exemple Point2.hh Point2.cc modPoint2.ph ====================Les fichiers .hh et .cc forment un programme C++ ordinaire, avec des classes et des fonctions, sans toutefois de fonction principale (main). Avant d'expliquer la génération d'interface, montrons le résultat: on peut, sous Ravi, charger un "module" modPoint, contenant les classes et les fonctions C++, et les appeler depuis Scheme, voici un exemple de session:
ensibull{62} ravi verbose
Ravi....Fichier Charge : /home/perms/lux/Ravi/Ravi2/Runtime/newravi.mobj......MV ready.......... GO !!!!
Chargement de /home/perms/lux/Ravi/Ravi2/Runtime/Init.scm
Chargement de /home/perms/lux/.RaviInit.scm
:>(setinputportci)
necessaire à présent pour distinguer maj/minuscules
> à mettre dans votre .RaviInit.scm
:> (require 'help)
...
:>(load "modPoint.x.scm")
= Chargement de ./modPoint.x.scm
Chargement de /home/perms/lux/Ravi/Ravi2/Module/rooc++.mobj
Chargement de ./modPoint.so
; ** Time : 0.10 sec
on voit qu'il y a chargement de plusieurs fichiers, dont un .so
avec le code C++
Maintenant on peut utiliser les fonctions chargées
:>(define p1 (new Point))
=
:>p1
= <Point : (0 0)>
:>(define p2 (new Point 20 30))
=
:>(send p2 GetX)
=
:>(send p1 = p2)
= <Point : (20 30)>
:>(send p1 GetX)
= 20
Puis les possibilités offertes par le help:
:>(help Point)
= Point is C++ class
MODULE : ("modPoint")
methods are:
1 (Point GetX)
2 (Point GetY)
3 (Point SetX)
4 (Point SetY)
5 (Point Set)
6 (Point (coperator =))
7 (Point ObjectInfo)
8 (Point constructor)
" "
:>(help 5)
= Point::Set defined with 2 profiles:
void Set(Point &);
void Set(int,int);
Un opérateur est appelé comme une méthode:
:>(send p1 = p2)
= <Point : (20 30)>
On voit bien dans cet exemple que ces choses ont été ajoutées au code C++
initial pour l'interfacer avec Scheme.
C'est le rôle du fichier modPoint.ph.
======================================================================
Le code d'interface est généré à partir d'un fichier .ph, qui "déclare" quelles fonctions/classes on veut interfacer en fournissant les déclarations C++ correspondantes. Nous présentons 2 variantes ... nous avons beaucoup fouillé pour trouver les bonnes commandes, finalement, les 2 fonctionnent pareil. Variante 1 réalisée pour le module modPoint. Variante 2 réalisée pour le module modPoint2. Les commandes de génération sont regroupées dans un makefile: il suffit de taper (variante 1) makefile modPoint.so Pour l'exemple du module modPoint, cela correspond aux commandes suivantes: version AIX
======== Variante 1 : le .cc est recopié dans le .ph
======== Avantage : moins de fichiers à manipuler
======== Inconvénient : duplication du .cc
ravi mod rig modPoint
g++ fPIC c DDEBUG_LEVEL=0 O2 I$RAVIREP/Include \
o modPoint.o modPoint.cc
rm modPoint.so
./ldAix modPoint.o modPoint.so
======== Variante 2 : séparation complète entre .cc et .ph
======== Avantage : code C++ totalement indépendent
======== Inconvénient : plus de fichiers
Pas de makefile pour l'instant!
g++ fPIC c DDEBUG_LEVEL=0 O2 o Point2.o Point2.cc
ravi mod rig modPoint2
g++ fPIC c DDEBUG_LEVEL=0 O2 I$RAVIREP/Include \
o modPoint2.o modPoint2.cc
rm modPoint2.so
./ldAix modPoint2.o modPoint2.so Point2.o
RemarquesfPIC format Position Independent Code, format de sortie nécessaire pour les librairies partageables. ldAix est un script qui appèle le chargeur système (commande ld) avec les bons paramètres. Il crée le fichier .so qui contient du code partageable attention à l'ordre des arguments: le 2ième argument est le fichier de sortie, les arguments suivants (maximum $9) sont des fichiers de données. Le fichier de sortie ne doit pas déjà exister,d'où l'emploi du rm. ldAix génère notamment un fichier lib.exp avec les noms à exporter. Il provoque une foule de warning qu'on peut ignorer. Plein de défaut on devrait améliorer ce script! (voir man ld pour rentrer dans les détails.) Pour en savoir plus sur la génération d'interfaces, voir le fichier Doc/interfaceC++. (qui évoluera rapidement dans les prochains jours). ======================================================================Commandes de compilation sous Linux
g++ c fPIC Point.cc
g++ shared lg++ o libpoint.so Point.o
ravi mod rig modPoint
g++ c fPIC I${RAVIREP}/Include modPoint.cc
g++ shared lg++ o modPoint.so modPoint.o lpoint L.
de meme pour Point2
g++ c fPIC Point2.cc
g++ shared lg++ o libpoint2.so Point2.o
ravi mod rig modPoint2
g++ c fPIC I${RAVIREP}/Include modPoint2.cc
g++ shared lg++ o modPoint2.so modPoint2.o lpoint2 L.
========================================================================
|