Bonjour,
J'ai besoin d'utiliser argc et argv dans une fonction assez loin du main.
Existe-il un moyen de récupérer ces arguments sans les faire passer d'objet en objet?
Merci.
Version imprimable
Bonjour,
J'ai besoin d'utiliser argc et argv dans une fonction assez loin du main.
Existe-il un moyen de récupérer ces arguments sans les faire passer d'objet en objet?
Merci.
Bonsoir,
le meilleur moyen serait de les passer en paramètre des appels nécessaires.
Une autre "technique" moins propre pourrait consister à les stocker quelque part d'accessible depuis le 2° endroit. Après y'a des niveaux dans la propreté : en global, beurk, dans une classe spéciale avec add/get pourquoi pas, et on peut imaginer plusieurs variantes..
:cry:Rappel : argc et argv sont deux constantes. N'étant pas modifiables, elles ne peuvent pas poser de problème si elle sont stockées en tant que globales.
Personnellement, je préfèrerais une autre approche, plus idiomatique : les traiter dans main(), et définir les conditions qui seront passées aux autres entités du programme. Ca n'a pas de sens de passer argc/argv à une fonction "assez loin de main" (quoi que ça signifie).
J'utilise une bibliothèque de résolution de systèmes linéaires qui requiert ces paramétres.
Elle est nécessaire dans la classe en bout de chaîne :
main
-> classe centrale des calculs
-> classe représentant une matrice avec un sens physique
-> classe de matrice creuse (abstraite)
-> classe représentant le format Csc (où j'utilise la bibliothèque de résolution)
De plus, il y a 4 classes qui dérivent de la classe matrice creuse ( ce serait dommage de leur faire passer argc et argv à tous)
Je vais essayer de les mettre en global
Merci en tout cas
Salut,
Déjà, il faudrait savoir quels sont les paramètres que tu envisages de récupérer par argv...
De prime abord, je dirait que, outre quelques flags éventuels, c'est essentiellement des noms de fichiers (un pour le nom de fichier d'entrée voire, peut etre un deuxième pour un nom de fichier de sortie).
Je te vois en effet assez mal commencer à fournir l'ensemble des valeurs d'une matrice à la main :D
Si je ne me trompe pas, le noms de fichier reçu sera sans doute au format csc, et la première chose que tu devras faire, c'est... lire le fichier d'entrée avec un instance de la classe qui gère ce format.
Si nom de sortie il y a, tu devras éventuellement le fournir à une deuxième de la classe qui gère le format afin de lui demander d'y écrire la matrice résultante.
Enfin, si flags il y a, c'est à 'instance de la classe de calcul qu'ils seront destinés afin de lui demander de faire les manipulation ad-hoc.
Mais cela signifie que ta classe gérant le format csc (je n'en connais pas le nom, donc je vais considérer qu'elle s'appelle "LibClass" :D) présente sans doute une interface qui permet:
- de lire un fichier dont on donne le nom ( read(filename) :question:)
- d'écrire dans un fichier dont on donne le nom ( write(filename) :question:)
- d'avoir quelques test pour savoir si c'est une matrice creuse ou pas (isEmpty(), isHollow(), isFull() :question:)
- de transmettre une matrice (creuse ou non)
- de récuprer une matrice (creuse ou non)
Au final, ta fonction main devrait pouvoir ressembler, au pire, à quelque chose comme:
Au mieux, toute cette logique est exécutée dans ta classe "calcul" et ta fonction main ressemblerait alors à quelque chose commeCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 int main(int argc char **argv) { /* récupération des arguments, dont le fichier d'entrée (inFilename) * le fichier de sortie (outFilename), et les différents flags */ LibClass reader; reader.read(inFilename); Calculator calc; /* un type */ result if(reader.isHollow() ) { HollowMatrix mat= reader.getHollow(); result = calc.execute( mat /* flags */ } else { FullMatrix mat= reader.getFull(); result = calc.execute( mat /* flags */ } LibClass writer; writer.setMatrix(result); writer.write(outFilename); return 0; }
Et c'est la classe que j'ai nommé "Calculator" qui maintiendra les différents arguments et qui les utilisera pour demander à "LibClass" de lire ou d'écrire dans le nom de fichier, voire pour invoquer d'autres classes de la bibliothèque (car je présume qu'elle ne fait pas que lire et écrire dans un format donné :D ) quand c'est utile, dans une des fonctions appelée (peut etre de manière indirecte :D) depuis la fonction execute ;)Code:
1
2
3
4
5
6
7
8
9
10
11 int main(int argc, char ** argv) { /* récupération des arguments, dont le fichier d'entrée (inFilename) * le fichier de sortie (outFilename), et les différents flags */ Calculator calc; calc.setInFilename(inFilename); calc.setOutFilename(outFilename); calc.setFlags(flags); calc.execute(); return 0; }
Ce qu'il faut comprendre, c'est que tes classe (dérivant de) "matrice creuse" et "matrice pleine" ne devrait pas avoir à connaitre les classes offertes par ta bibliothèque manipulant le format csc.
Il doit, éventuellement, y avor des possibilités de conversions entre tes classes et celles de la bibliothèque, mais tes propres classe ne sont là que pour servir "d'intermédiaire" éventuel entre les différentes parties de l'application, dont, pourquoi pas, pour être transmise à une IHM quelconque ;)
Au passage, une matrice contenant essentiellement des valeurs numérique, elle a, classiquement, une sémantique de valeur (ce n'est, après tout, qu'un ensemble cohérent de valeurs ;) :D ) et ne devrait donc pas servir de base à une hiérarchie de classe (pas d'héritage ;) )
Ce sont des paramétres utiles à la bibliothèque de résolution pour son passage en MPI. C'est donc le nombre de processeurs et la liste des machines disponibles.
Mais c'est bien argc et argv dont j'ai besoin : la bibliothèque (écrite en C) doit être utilisée en commençant par MPI_Init_thread(&argc, &argv, required, &provided);
Le remplissage de la matrice se fait au fur et à mesure d'un calcul dans une autre classe
En fait on donne à l'exécution quel format de matrice on veut utiliser, pour pouvoir réaliser des comparaisons plus facilement (les bibliothèques de résolutions d'équation linéaires ne fonctionnent pas toutes avec le même format)
Elles ne les connaissent pas. La classe abstraite gérant les matrices creuse ("ISparseMat") posséde une méthode virtuelle solve()=0; , et chaque classe dérivé posséde sa propre bibliothèque de résolution adapté à son format
Le fait qu’ils aient repris ces noms ne veut pas dire que tu ne peux pas lui envoyer tout ce que tu veux. Le tout est que ça respecte le format, à savoir, argc = nombre d’arguments, argv = tableau des arguments.
Le seul intérêt que je vois à passer directement argc et argv de ton programme, c’est si :
- tu es sûr que tes paramètres à toi de ton programme ne pollueront pas l’analyse de paramètres de la bibliothèque
- tu veux que la bibliothèque puisse être mise à jour, et accepter de nouveaux paramètres, sans modifier ton application.
Ça me semble un cas d’utilisation limité, mais ça peut se justifier. Je conseillerai toutefois plutôt que ce soit ton programme qui gère les arguments, et qu’il construise ce qu’il passe à la librairie à partir de ses propres arguments (quitte à accepter et passer tel quel à la librairie tout argument arbitraire situé après, par exemple, « -- » dans la ligne de commande, ce qui permet de garder l’extensibilité).