Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
855 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Question pour un champion [1]

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

Question pour un champion [1]

n°662983
docmaboul
Posté le 04-03-2004 à 15:30:20  profilanswer
 

Soit une jolie instance de classe allouée en shared memory.
Soit un fou ne possédant pas gcc et n'ayant pas d'option pic ou équivalent sur son compilo.
Comment fera notre fou pour appeler les méthodes de son objet directement dans les différents process l'utilisant ?
 
En clair, comment fera-t-il :
 

Code :
  1. class blabla
  2. {
  3. public:
  4.   // ...
  5.   void toto(int);
  6.   // ...
  7. };
  8. // pObjetBlabla est en shared
  9. void func(blabla * pObjetBlabla)
  10. {
  11.   // ...
  12.   pObjetBlabla->Toto(0);
  13.   // ...
  14. }


 
astuce: c'est faisable.

mood
Publicité
Posté le 04-03-2004 à 15:30:20  profilanswer
 

n°663023
Taz
bisounours-codeur
Posté le 04-03-2004 à 15:57:38  profilanswer
 

Code :
  1. #include <iostream>
  2. #include <stdexcept>
  3. extern "C"
  4. {
  5. #include <unistd.h>
  6. #include <sys/ipc.h>                                                         
  7. #include <sys/shm.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <sys/wait.h>
  12. }
  13. class Foo
  14. {
  15.   char filler;
  16. public:
  17.   void bar()
  18.   {
  19.     std::cout << "Hello\t"
  20.       << getpid() << '\n';
  21.   }
  22. };
  23. class ErrnoError
  24.   : public std::runtime_error
  25. {
  26. public:
  27.   ErrnoError()
  28.     : std::runtime_error(strerror(errno))
  29.   {}
  30. };
  31. int main(int argc, char *argv[])
  32.   try
  33. {
  34.   key_t key = ftok(argv[0], 42);
  35.   if(key == -1) { throw ErrnoError(); }
  36.   int shm = shmget(key, sizeof(Foo), IPC_CREAT | 0600);
  37.   if(shm == -1) { throw ErrnoError(); }
  38.   void * const mem = shmat(shm, NULL, 0); 
  39.   if(not mem) { throw ErrnoError(); }
  40.   Foo *f =  new(mem) Foo;
  41.   switch(fork())
  42.     {
  43.     case -1:
  44.       throw ErrnoError();     
  45.     case 0:
  46.       std::cout << getpid() << " a été créé par " << getppid() << '\n';
  47.       f->bar();
  48.       shmdt(mem);
  49.       break;
  50.      
  51.     default:
  52.       wait(NULL);
  53.       f->bar();
  54.       shmdt(mem); 
  55.       if(shmctl(shm, IPC_RMID, 0) == -1) { throw ErrnoError(); }
  56.     }
  57. }
  58. catch(std::exception &e)
  59. {
  60.   std::cerr << "Aïe\t" << e.what() << std::endl;
  61. }

n°663066
docmaboul
Posté le 04-03-2004 à 16:39:01  profilanswer
 

Groumf, j'ai oublié de préciser que la classe se trouve dans une librairie chargée dynamiquement, par le code, au runtime.
 
Mea culpa.
 
(mais c'était tellement facile que t'aurais pu te douter qu'il y avait une couille dans le steak là)

n°663073
Taz
bisounours-codeur
Posté le 04-03-2004 à 16:41:10  profilanswer
 

DocMaboul a écrit :

Groumf, j'ai oublié de préciser que la classe se trouve dans une librairie chargée dynamiquement, par le code, au runtime.

et ça change quoi ?
 

DocMaboul a écrit :


(mais c'était tellement facile que t'aurais pu te douter qu'il y avait une couille dans le steak là)

t'as jamais fait la preuve de tes compétences

n°663075
Taz
bisounours-codeur
Posté le 04-03-2004 à 16:43:23  profilanswer
 

DocMaboul a écrit :

la classe se trouve dans une librairie chargée dynamiquement


 

DocMaboul a écrit :

Soit une jolie instance de classe allouée en shared memory.

 
 
et après si tu commençais à bien nommer les choses, on comprendrais mieux. la provenance de la classe n'a aucune importance. dès que t'en as la définition, tu cases tes instances où tu veux

n°663090
docmaboul
Posté le 04-03-2004 à 16:51:24  profilanswer
 

Taz a écrit :


et après si tu commençais à bien nommer les choses, on comprendrais mieux.


 
Mea culpa again.
 
"la provenance de la classe n'a aucune importance. dès que t'en as la définition, tu cases tes instances où tu veux"
 
pas tout à fait. Si tu ne fais pas un fork mais que tu utilises réellement deux programmes différents, l'histoire n'est pas la même.
 
En plus, je ne te demande pas du code mais la méthode à utiliser (mais si tu veux mettre le code, libre à toi). Et je précise bien, cette fois, : que la méthode en question marche aussi sous windows.


Message édité par docmaboul le 04-03-2004 à 16:52:16
n°663107
Taz
bisounours-codeur
Posté le 04-03-2004 à 17:03:16  profilanswer
 

mais tu veux faire quoi ? si tu veux partager une instance, il faut de la mémoire partagée ou tout autre mécanisme de communication à la IPC

n°663109
docmaboul
Posté le 04-03-2004 à 17:04:52  profilanswer
 

Taz a écrit :

t'as jamais fait la preuve de tes compétences


 
Oui : je n'ai rien à prouver. Ni à toi ni à personne d'ailleurs.
 
Bon, et pour revenir au sujet, t'as trouvé la solution, champion ?

n°663114
docmaboul
Posté le 04-03-2004 à 17:08:52  profilanswer
 

Taz a écrit :

mais tu veux faire quoi ? si tu veux partager une instance, il faut de la mémoire partagée ou tout autre mécanisme de communication à la IPC


 
Bon, je reformule. Le contexte est :
Soit deux programmes partageant une même zone de mémoire (la méthode de sharing, je m'en fous)
Les deux programmes chargent la même librairie au runtime.
Un des deux (peu importe lequel) crée une instance de classe dans la mémoire partagée.
La classe en question est définie dans la librarie.
 
Le problème est :
trouver une méthode pour pouvoir utiliser les méthodes de la classe directement dans les deux programmes (la méthode doit aussi marcher sous windows).

n°663119
Taz
bisounours-codeur
Posté le 04-03-2004 à 17:12:04  profilanswer
 

ben mon code réponds à ton problème. le processus initial crée un segment de mémoire partagée, y instancie un objet, et un autre processus (ici créé par fork pour avoir à réécrire les instructions pour attacher le segment de mémoire). et les deux programmes utilisent le même objet. le processus initial a également la charge de détruire le segment partagé

mood
Publicité
Posté le 04-03-2004 à 17:12:04  profilanswer
 

n°663131
docmaboul
Posté le 04-03-2004 à 17:16:23  profilanswer
 

Taz a écrit :

ben mon code réponds à ton problème. le processus initial crée un segment de mémoire partagée, y instancie un objet, et un autre processus (ici créé par fork pour avoir à réécrire les instructions pour attacher le segment de mémoire). et les deux programmes utilisent le même objet. le processus initial a également la charge de détruire le segment partagé


 
malheureusement non car sans pic, les fonctions de l'objet pointeront sur des adresses relatives à l'adressage du programme ayant créé l'objet. Et l'autre plantera.

n°663134
Taz
bisounours-codeur
Posté le 04-03-2004 à 17:17:27  profilanswer
 

ben vois avec ton système.
 
chaimoiçamarche

n°663180
docmaboul
Posté le 04-03-2004 à 17:31:49  profilanswer
 

Taz a écrit :

ben vois avec ton système.
 
chaimoiçamarche


 
A d'autres : c'est du pipeau.

n°663381
blackgodde​ss
vive le troll !
Posté le 04-03-2004 à 18:59:52  profilanswer
 

en passant par une interface et en faisant un allocateur commun ?
 
c le 1er truc qui me passe par la tete, je v tester ^^


---------------
-( BlackGoddess )-
n°663382
Taz
bisounours-codeur
Posté le 04-03-2004 à 19:00:36  profilanswer
 

BlackGoddess a écrit :

en passant par une interface et en faisant un allocateur commun ?
 
c le 1er truc qui me passe par la tete, je v tester ^^

ben c'est en simple ce que fait le placement de new. et ça fonctionne bien

n°663494
blackgodde​ss
vive le troll !
Posté le 04-03-2004 à 20:25:37  profilanswer
 

bon, j'ai trouvé une solution sous windows, je sais pas si c'est ce qui etait attendu ...
 
je pars du principe d'une shared section, et du principe que le code dans la dll est aussi bien utilisable par un prog que par l'autre.
 
j'ai donc fait 3 executables : une dll contenant une classe contenant une variable, un exe changeant cette variable, et un exe la lisant.
 
header commun :
 

Code :
  1. struct i_test
  2. {
  3. virtual int get() const = 0;
  4. virtual void set(const int & ) = 0;
  5. };


 
dll :

Code :
  1. #include <windows.h>
  2. #include <iostream>
  3. #include "hdr.h"
  4. #pragma section("myshared", shared)
  5. class test : public i_test
  6. {
  7. int i;
  8. public:
  9. int get() const
  10. {
  11.  return i;
  12. }
  13. void set(const int & var)
  14. {
  15.  i = var;
  16. }
  17. };
  18. __declspec(allocate("myshared" )) test shared_test;
  19. i_test * WINAPI get_test()
  20. {
  21. return &shared_test;
  22. }


 
(on lui fait exporter le symbole get_test)
 
programme changeant la variable :

Code :
  1. #include <windows.h>
  2. #include <iostream>
  3. #include "../dlltest/hdr.h"
  4. typedef i_test *(WINAPI*p_alloc_test)();
  5. typedef i_test *(WINAPI*p_get_test)();
  6. int main()
  7. {
  8. HMODULE hm = LoadLibrary("dlltest.dll" );
  9. //p_alloc_test alloc_test = (p_alloc_test)GetProcAddress(hm, "alloc_test" );
  10. p_get_test get_test = (p_get_test)GetProcAddress(hm, "get_test" );
  11. i_test *t = get_test();
  12. t->set(3);
  13. MessageBox(NULL, "test->set(3);", "test_alloc", NULL);
  14. FreeLibrary(hm);
  15. }


 
programme lisant la variable :
 

Code :
  1. #include <windows.h>
  2. #include <iostream>
  3. #include "../dlltest/hdr.h"
  4. typedef i_test *(WINAPI*p_alloc_test)();
  5. typedef i_test *(WINAPI*p_get_test)();
  6. int main()
  7. {
  8. HMODULE hm = LoadLibrary("dlltest.dll" );
  9. //p_alloc_test alloc_test = (p_alloc_test)GetProcAddress(hm, "alloc_test" );
  10. p_get_test get_test = (p_get_test)GetProcAddress(hm, "get_test" );
  11. i_test *t = get_test();
  12. if(t->get() == 3)
  13.  MessageBox(NULL, "test->get() == 3;", "test_get", NULL);
  14. else
  15.  MessageBox(NULL, "test->get() != 3;", "test_get", NULL);
  16. FreeLibrary(hm);
  17. }


 
(j'ai codé comme un cochon, c'etait juste pour voir si la solution que j'ai imaginé fonctionne)


---------------
-( BlackGoddess )-
n°663951
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 10:18:50  profilanswer
 

sinon pour plus de dynamisme, il faudrait déclarer un buffer dans la mémoire partagée, et faire un allocateur/libérateur pour gérer ce buffer.


---------------
-( BlackGoddess )-
n°664473
docmaboul
Posté le 05-03-2004 à 16:10:47  profilanswer
 

Taz a écrit :

ben c'est en simple ce que fait le placement de new. et ça fonctionne bien


 
c'est faux. Tout ce que fait un new placement, par défaut et qui n'a donc pas été surchargé, c'est :
inline void * operator new(size_t, void * p){return p;}

n°664477
Taz
bisounours-codeur
Posté le 05-03-2004 à 16:14:13  profilanswer
 

DocMaboul a écrit :


 
c'est faux. Tout ce que fait un new placement, par défaut et qui n'a donc pas été surchargé, c'est :
inline void * operator new(size_t, void * p){return p;}

et ça n'est pas bien suffisant dans un cas simple ? franchement t'es lourd. tu sors connerie sur conneries, tu te le joues mais on voit rien de concret ... si y a bien quelqu'un de capable d'écire un allocateur ici, c'est moi. seulement, pas là peine de sortir le marteau pour écraser une mouche, d'autant plus que tout ça me parait une très mauvaise idée, je préfère à ce moment utiliser un processus proxy avec une petite zone de mémoire partagée servant de tampon de communication, ou utiliser les autres mécanismes classiques de communication inter-processus

n°664491
docmaboul
Posté le 05-03-2004 à 16:23:12  profilanswer
 

BlackGoddess a écrit :

bon, j'ai trouvé une solution sous windows, je sais pas si c'est ce qui etait attendu ...


 
Non mais j'en suis responsable. Le problème est vieux et je l'ai très mal posé. Allez, la dernière mouture :
 
Soit une librairie dynamique tout ce qu'il y a de plus normale, comportant un bon gros millier de classes codées convenablement : à savoir sans saloperies comme les membres "static" et avec des allocateurs. Il y a des héritages entre ces classes et des jolies fonctions virtuelles à gogo. De plus, vous n'avez pas accès au code de la librairie. Quelle méthode utiliser pour pouvoir allouer les objets en shared memory et appeler les méthodes "normalement".
 
astuce 1: comme d'habitude, c'est faisable
astuce 2: la problématique se situe au niveau de la vtable des classes
astuce 3: on ne peut pas exécuter une fonction dont le code se trouve en shared avec la plupart des implémentations d'unix
astuce 4: si vous trouvez la seule méthode (à ma connaissance) clean, robuste et élégante, il y a peu de chance que vous puissiez l'implémenter

n°664496
Taz
bisounours-codeur
Posté le 05-03-2004 à 16:25:32  profilanswer
 

1) ne pas allouer en mémoire partagée
2) ne pas allouer en mémoire partagée
3) ne pas allouer en mémoire partagée
4) ne pas allouer en mémoire partagée
 
 
5) me rappelez de ne plus jamais lire tes conneries

n°664499
docmaboul
Posté le 05-03-2004 à 16:26:00  profilanswer
 

Taz a écrit :

et ça n'est pas bien suffisant dans un cas simple ? franchement t'es lourd. tu sors connerie sur conneries, tu te le joues mais on voit rien de concret ... si y a bien quelqu'un de capable d'écire un allocateur ici, c'est moi. seulement, pas là peine de sortir le marteau pour écraser une mouche, d'autant plus que tout ça me parait une très mauvaise idée, je préfère à ce moment utiliser un processus proxy avec une petite zone de mémoire partagée servant de tampon de communication, ou utiliser les autres mécanismes classiques de communication inter-processus


 
Mais je suis toujours près à admettre que je me trompe. Aussi montre moi donc le code de ce new qui ferait cet interfaçage. Pour le reste, tu peux toujours me sortir l'implémentation de com, ça fait dix ans que ça existe.
 
edit: ou presque...


Message édité par docmaboul le 05-03-2004 à 16:29:04
n°664503
docmaboul
Posté le 05-03-2004 à 16:27:31  profilanswer
 

Taz a écrit :

1) ne pas allouer en mémoire partagée
2) ne pas allouer en mémoire partagée
3) ne pas allouer en mémoire partagée
4) ne pas allouer en mémoire partagée
 
 
5) me rappelez de ne plus jamais lire tes conneries


 
6) et faire un vi de new.h [:ambesanch]

n°664513
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 16:35:54  profilanswer
 

DocMaboul a écrit :


avec des allocateurs.


 
bin l'allocateur de la lib va allouer sa mémoire a elle, dans l'espace du processus en cours, et aucun autre processus pourra la lire ...
 
sinon j'aurais dit recoder des allocateurs pour allouer sur un file mapping ...
 
ou sinon recoder un loader de librairie ...


Message édité par blackgoddess le 05-03-2004 à 16:39:39

---------------
-( BlackGoddess )-
n°664522
docmaboul
Posté le 05-03-2004 à 16:41:24  profilanswer
 

BlackGoddess a écrit :


 
bin l'allocateur de la lib va allouer sa mémoire a elle, dans l'espace du processus en cours, et aucun autre processus pourra la lire ...
 
sinon j'aurais dit recoder des allocateurs pour allouer sur un file mapping ...


 
Je voulais dire par là que tu peux lui faire utiliser un ou des allocateurs et que les classes fonctionneront donc 'à peu près' correctement en shared si l'allocateur leur donne de la shared.

n°664524
docmaboul
Posté le 05-03-2004 à 16:42:04  profilanswer
 

BlackGoddess a écrit :


ou sinon recoder un loader de librairie ...


 
Ca c'est intéressant. Pour quoi faire ?

n°664529
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 16:44:53  profilanswer
 

et bien un loader de librairie, qui devra intercepter les appels systemes de réservation/libération de la mémoire et les rediriger vers un endroit ou la mémoire est partagée (refaire un allocateur, mais à plus bas niveau)


---------------
-( BlackGoddess )-
n°664530
docmaboul
Posté le 05-03-2004 à 16:46:03  profilanswer
 

BlackGoddess a écrit :

et bien un loader de librairie, qui devra intercepter les appels systemes de réservation/libération de la mémoire et les rediriger vers un endroit ou la mémoire est partagée (refaire un allocateur, mais à plus bas niveau)


 
Je suis déçu... Quelle problématique veux-tu résoudre ainsi ?

n°664541
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 16:49:19  profilanswer
 

et bien, si toute l'utilisation mémoire de la librairie est ainsi gérée dans une zone partagée, les processus différents pourront y avoir accès ?


---------------
-( BlackGoddess )-
n°664548
docmaboul
Posté le 05-03-2004 à 16:52:33  profilanswer
 

BlackGoddess a écrit :

et bien, si toute l'utilisation mémoire de la librairie est ainsi gérée dans une zone partagée, les processus différents pourront y avoir accès ?


 
Ce n'est pas compliqué d'obtenir l'accès au data se trouvant dans la mémoire partagée. La problématique vient des tables virtuelles des différentes classes (mais je ne te dis pas exactement pourquoi histoire que tu te creuses un peu le neurone :-).

n°664551
bjone
Insert booze to continue
Posté le 05-03-2004 à 16:55:53  profilanswer
 

de quoi, que le pointeur à la table soit inconsistant entre les deux process ?

n°664554
docmaboul
Posté le 05-03-2004 à 16:57:22  profilanswer
 

bjone a écrit :

de quoi, que le pointeur à la table soit inconsistant entre les deux process ?


 
grosso merdo : bingo !

n°664555
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 16:58:48  profilanswer
 

qq1 m'explique o_O ?


---------------
-( BlackGoddess )-
n°664557
docmaboul
Posté le 05-03-2004 à 17:02:14  profilanswer
 

BlackGoddess a écrit :

qq1 m'explique o_O ?


 
La vtable d'une classe est globale et commune à toutes les instances. Elle est adressée dans l'espace du créateur de l'objet et donc relativement à celui-ci, idem pour les fonctions qu'elle référence. Dans un autre process, il y a très peu de chance que tu aies les mêmes adresses => access violation dès que tu appelles une virtuelle.

n°664558
bjone
Insert booze to continue
Posté le 05-03-2004 à 17:02:34  profilanswer
 

DocMaboul a écrit :


 
grosso merdo : bingo !


 
c'est cool, mais si tu avais mis un "virtual" devant ton toto, ça aurait été un peu plus évident.
 
si la méthode est pas virtual, ça pose pas de problèmes...
(malgré qu'il y ait des méthodes virtuelles)


Message édité par bjone le 05-03-2004 à 17:07:05
n°664561
blackgodde​ss
vive le troll !
Posté le 05-03-2004 à 17:04:19  profilanswer
 

bien :) merci de l'explication :)
 
tu sais ou trouver une implémentation de ce truc ? :p


---------------
-( BlackGoddess )-
n°664566
docmaboul
Posté le 05-03-2004 à 17:07:24  profilanswer
 

bjone a écrit :


 
c'est cool, mais si tu avais mis un "virtual" devant ton toto, ça aurait été un peu plus évident.
 
si la méthode est pas virtual, ça pose pas de problèmes...


 
C'est vrai et j'ai regretté d'avoir donné cet exemple qui n'était là que pour dire qu'en plus, je voulais une solution vraiment belle, c'est-à-dire sans un interfaçage à la mords-moi-le-com. Au lieu de clarifier, ça a embrouillé. Désolé.

n°664568
docmaboul
Posté le 05-03-2004 à 17:10:35  profilanswer
 

BlackGoddess a écrit :

bien :) merci de l'explication :)
 
tu sais ou trouver une implémentation de ce truc ? :p


 
Je n'en connais pas d'implémentation open source, ni même licenciée.

n°664569
bjone
Insert booze to continue
Posté le 05-03-2004 à 17:11:08  profilanswer
 

ceci dit, donc l'astuce ce serait quoi ?
 
d'utiliser un XXXX_cast<blabla> pour court-circuiter l'accès au pointeur vtable de l'instance ?
 
nope ça marcherai po des classes dérivée....


Message édité par bjone le 05-03-2004 à 17:13:17
n°664577
docmaboul
Posté le 05-03-2004 à 17:16:51  profilanswer
 

bjone a écrit :

ceci dit, donc l'astuce ce serait quoi ?


 
Malheureusement, il n'y a pas d'astuce (ça se saurait).
 
Faut juste être complètement fou.

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Question pour un champion [1]

 

Sujets relatifs
2 petites question de rien du tout = pb email et HTML ... merci......Question sur select()
petite question avec GTKbonjour, est il possible de vous poser une question a propos de CSS ??
[JAVA] Question à propos des FlowLayout()[C] Question sur strtol (conversion de char* en int)
[Visual C++] Question (basique) sur les CPenQuestion Parsage avec SAX ...
[lisp] petite question sur implodechQuestion pour un champion...
Plus de sujets relatifs à : Question pour un champion [1]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR