Question pour un champion [1] - C++ - Programmation
Marsh Posté le 04-03-2004 à 15:57:38
Code :
|
Marsh Posté le 04-03-2004 à 16:39:01
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à)
Marsh Posté le 04-03-2004 à 16:41:10
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 : |
t'as jamais fait la preuve de tes compétences
Marsh Posté le 04-03-2004 à 16:43:23
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
Marsh Posté le 04-03-2004 à 16:51:24
Taz a écrit : |
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.
Marsh Posté le 04-03-2004 à 17:03:16
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
Marsh Posté le 04-03-2004 à 17:04:52
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 ?
Marsh Posté le 04-03-2004 à 17:08:52
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).
Marsh Posté le 04-03-2004 à 17:12:04
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é
Marsh Posté le 04-03-2004 à 17:16:23
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.
Marsh Posté le 04-03-2004 à 17:31:49
ReplyMarsh Posté le 04-03-2004 à 18:59:52
en passant par une interface et en faisant un allocateur commun ?
c le 1er truc qui me passe par la tete, je v tester ^^
Marsh Posté le 04-03-2004 à 19:00:36
BlackGoddess a écrit : en passant par une interface et en faisant un allocateur commun ? |
ben c'est en simple ce que fait le placement de new. et ça fonctionne bien
Marsh Posté le 04-03-2004 à 20:25:37
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 :
|
dll :
Code :
|
(on lui fait exporter le symbole get_test)
programme changeant la variable :
Code :
|
programme lisant la variable :
Code :
|
(j'ai codé comme un cochon, c'etait juste pour voir si la solution que j'ai imaginé fonctionne)
Marsh Posté le 05-03-2004 à 10:18:50
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.
Marsh Posté le 05-03-2004 à 16:10:47
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;}
Marsh Posté le 05-03-2004 à 16:14:13
DocMaboul 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
Marsh Posté le 05-03-2004 à 16:23:12
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
Marsh Posté le 05-03-2004 à 16:25:32
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
Marsh Posté le 05-03-2004 à 16:26:00
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...
Marsh Posté le 05-03-2004 à 16:27:31
Taz a écrit : 1) ne pas allouer en mémoire partagée |
6) et faire un vi de new.h
Marsh Posté le 05-03-2004 à 16:35:54
DocMaboul 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 ...
ou sinon recoder un loader de librairie ...
Marsh Posté le 05-03-2004 à 16:41:24
BlackGoddess a écrit : |
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.
Marsh Posté le 05-03-2004 à 16:42:04
BlackGoddess a écrit : |
Ca c'est intéressant. Pour quoi faire ?
Marsh Posté le 05-03-2004 à 16:44:53
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)
Marsh Posté le 05-03-2004 à 16:46:03
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 ?
Marsh Posté le 05-03-2004 à 16:49:19
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 ?
Marsh Posté le 05-03-2004 à 16:52:33
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 :-).
Marsh Posté le 05-03-2004 à 16:55:53
de quoi, que le pointeur à la table soit inconsistant entre les deux process ?
Marsh Posté le 05-03-2004 à 16:57:22
bjone a écrit : de quoi, que le pointeur à la table soit inconsistant entre les deux process ? |
grosso merdo : bingo !
Marsh Posté le 05-03-2004 à 17:02:14
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.
Marsh Posté le 05-03-2004 à 17:02:34
DocMaboul 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...
(malgré qu'il y ait des méthodes virtuelles)
Marsh Posté le 05-03-2004 à 17:04:19
bien merci de l'explication
tu sais ou trouver une implémentation de ce truc ?
Marsh Posté le 05-03-2004 à 17:07:24
bjone a écrit : |
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é.
Marsh Posté le 05-03-2004 à 17:10:35
BlackGoddess a écrit : bien merci de l'explication |
Je n'en connais pas d'implémentation open source, ni même licenciée.
Marsh Posté le 05-03-2004 à 17:11:08
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....
Marsh Posté le 05-03-2004 à 17:16:51
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.
Marsh Posté le 04-03-2004 à 15:30:20
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 :
astuce: c'est faisable.