mercredi 13 janvier 2010

Utilisation de bibliothèques dynamiques en C++

Vous essayez de manipuler ça pour que vos programmes soit plus utilisables ?
Ok, c'est pas SI compliqué .

Tout d'abord, pas de baratin, voilà LA page que vous DEVEZ consulter pour comprendre tout ça rapidement et simplement :

http://hiko-seijuro.developpez.com/articles/bibliotheque-dynamique


MAis, ...croyez-moi, ça va pas vous suffire quand même.

Y'a un souci majeur : les dépendances des librairires dynamiques qu'on utilise.

Voici mon exemple.

class c1  qui est tranformée en librairie l1
class c2  et c3 qui sont transformées en l2

dans mon main,
je load la librairie l2, et j'utilise c2,
je load la librairie l1, et j'utilise c1

je fais ces loads à partir du chemin absolu des librairies car ce sont les miennes et elles sont pas enregistrées dans usr/lib ou je ne sais quel autre.
(ou j'utilise une factory comme c'est proposé dans le tuto (qui est super hein ;) )).


Ma classe c1 elle hérite d'une classe c3.

Donc quans je load ma librairie l1, mon appel à dlfcn va automatiquement chercher à loader la librairie l2 dont dépend l1.

Et là GROS problème car dlfcn cherche les chemins "systeme" et ne trouve donc plus ma librairie l2.

Solution :

vous utilisez la commande :

env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:le_chemin_vers_vos_librairies ./votre_executable



Vous pouvez mettre ça dans un script bash bien sûr ;).
Il vous reste uniquement à indiquer les chemins vers vos librairies perso pour que dlfcn les trouve lors de l'exécution.


Voilou,
enjoy

Les stringstream en C++

Vous vous galérez encore à manipuler les char* ? et ça vous énerve de faire les transformations string <-> char* ?

Ok, si vous connaissez un peu de syntaxe C++, ces bouts de code devraient bien vous intéresser.

Vous allez voir, c'est magique dès qu'on a les fonctions clés.

Pour le principe, les stringstream sont des flux du même genre que cout, cin et cerr. Mais vous pouvez les manipuler comme des chaines de caractères ... !!!

Vous avez besoin d'ouvrir un nouveau fichier main.cc et d'y mettre :

#include   //Pour faire des cout

#include     //Pour jouer dans un fichier

#include    //Pour utiliser les stringstream

#include    //Pour utiliser aussi des strings


using namespace std;


//Ok nous voilà parés


int main(){

//J'ai une variable quelconque

int a = 2;

//Je veux un stringstream
stringstream ss;


//je veux un fichier (non vide c mieux ^^)
fstream f("votre_fichier",fstream::in);  //Notez le fstream::in, qui permet d'ouvrir en lecture)

//Je vais lire mon fichier jusqu'au bout, en récupérant chaque 'mot'
// les 'mots' sont séparés par des espaces

//Je prend une chaine de caractères
string c;

while(f.good())
{
  f >> c;
}

//dans c , vous avez le dernier mot lu.
//vous pouvez par exemple prévenir que :

ss << "Dernier mot lu : " << c << endl;

cout << ss.str();

//On a mis le message dans le stringstream et on affiche le contenu du //stream dans cout ensuite.


//On récupère la string correspondant au stream avec :
  string contenu= ss.str();

//et on peut avoir ça en char*, pour les string et les streams avec :

char* contenu = new char[100];
contenu = c.c_str();

//Ou

contenu = ss.str().c_str();


//C'est pratique aussi pour passer des commandes système
//vous ajoutez :
#include //Pour appeler la commande system

//Et vous faite votre commande avec le stream

ss << "cp " << monfichier.str() << "_version" << numversion;

//Par exemple :D
//Puis

system(ss.str().c_str());

//Enfin, le dernier truc magique indispensable,
//Pour remettre à zéro un stream qui contient déjà quelque chose
ss.str("");

//Simplissime ? ... ouais c sur, mais faut juste le savoir :), c ça qu'est bon

};




Voilà un premier exemple sur les stringstream, testez ça, c'est magique.
Depuis que j'ai commencé, je ne peux plus arrêter ^^... je suis accro


À vous d'jouer.

mardi 27 octobre 2009

Distance entre deux éléments situés dans 2 espaces différents projettés l'un sur l'autre

#include
#include
#include



using namespace std;




float calcDistance(int num_pop_a, int num_pop_b, float* c_a,
           float* c_b, int d_a,int d_b,int***mapping){
  int d_max;
  if(d_a > d_b)
    d_max = d_a;
  else
    d_max = d_b;

  float* dists = new float[d_max];
  for(int i = 0; i < d_max; ++i)
    if((mapping[num_pop_a][num_pop_b][2*i] == -1) ||
       (mapping[num_pop_a][num_pop_b][(2*i)+1] == -1))
      dists[i] = 0;
    else
      {
    dists[i] = c_b[mapping[num_pop_a][num_pop_b][(2*i)+1]] - c_a[mapping[num_pop_a][num_pop_b][2*i]];
    dists[i] *= dists[i];
      }
  float distance = 0;
  for(int i = 0; i < d_max; ++i)
    distance += dists[i];

  return sqrt(distance);
}

//Fournir la distance entre 2 points situés dans des espaces de dimension kkonque.
// Si dimension différente pour les 2 espaces, les distances dans les dimension n'existant pas
//dans un des espaces sont nulles.
//Un "mapping" des coordonnées entre les espaces contenant l'élément pré et l'élément post est fourni
int main(int argc, char* argv[]){

  int dim_e_A = 1;
  int dim_e_B = 2;

  float* coords_p_A = new float[dim_e_A];
  float* coords_p_B = new float[dim_e_B];

  //tableau contenant une matrice 2D représentant
  // les projections possibles entre les espaces considérés
  // ici A est dans un espace et B dans un autre
  int*** mapping = new int**[2];

  //Projections de l'espace de A
  mapping[0] = new int*[2];
  //Projections de l'espace de B
  mapping[1] = new int*[2];

  //Projection qu'on utilise ici A -> B
  mapping[0][1] = new int[4];

  //On indique dans la 3eme dimension du tableau
  // les correspondances entre les dimensions des deux espaces
  // considérés.
  // Ici : A : 1 coords (X:0), B : 2 coords : (X:0,Y:1)
  //le -1 indique 'pas de coordonnées'
  //Dans cet exemple, X_A correspond à X_B
  //mapping[0][1][0] = 0;
  //mapping[0][1][1] = 0;
  //mapping[0][1][2] = -1;
  //mapping[0][1][3] = 1;

  //Dans cet exemple, X_A correspond à Y_B
  mapping[0][1][0] = -1;
  mapping[0][1][1] = 0;
  mapping[0][1][2] = 0;
  mapping[0][1][3] = 1;

  coords_p_A[0] = 2;

  coords_p_B[0] = 1;
  coords_p_B[1] = 5;

  float distance = calcDistance(0,1,coords_p_A,coords_p_B,dim_e_A,dim_e_B,mapping);

  cout << "distance A - B = " << distance << endl;
  return 1;
};

dimanche 25 octobre 2009

Fournir les coordonnées du ieme élément d'une matrice de D dimensions de même taille contenant N éléments.



 


#include
#include
#include



using namespace std;




void calcCoords(int index, int taille_dim, int nb_dims, int i, int* coordonnees)
{
  coordonnees[i] = index % taille_dim;
  if(nb_dims!=0)
    calcCoords(index/taille_dim,taille_dim,nb_dims-1,i+1,coordonnees);       
}

void coords(int index, int taille_tot, int nb_dims, int* coordonnees)
{
  calcCoords(index,(int)pow(taille_tot,1.0/nb_dims),nb_dims,0,coordonnees); 
}


//Fournir les coordonnées du ieme élément d'une matrice de D dimensions de même taille contenant N éléments.

int main(int argc, char* argv[]){

  if(argc != 4)
    cout << "pas le bon nb d'args" << endl;
  else
    {
      int index_elem = atoi(argv[1]);
      int nb_elem = atoi(argv[2]);
      int nb_dims = atoi(argv[3]);

      int* coordonnees = new int[nb_dims];
      coords(index_elem, nb_elem, nb_dims,coordonnees);
     

      for(int i = 0; i < nb_dims; ++i)
    cout << "dimension " << i << " coord : " << coordonnees[i] << endl;
    }
  return 1;
};