1

suite du post:
topics/44988-validation-de-procedure-dll

La procédure étant validée..

Etat des lieux:

Je fais partie d'une équipe (bénévole) pour l'amélioration d'un jeu de simulation, Fa18 jane's , La socièté EA US n'ayant plus les sources, nous avons eu l'accord de travailler sur le code assembleur..vive le reverse enginering!! bref..

L'assembleur va bien un moment..Le problème qui se pose est d'attaquer une DLL dont on a juste une description des fonctions/classes dans un Header..

// skunkcmp.h
// my attempt at the class spec for:
// CCat
#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */



//------------------------------------------------------------------
// CLASS CCat
// Supports read/write of a file type called a catalog.
// A catalog contains one or more compressed data files.
// The first 32bit word in the file is the number of data files.
// 4 more unknown words follow. The file record table then follows.
// It is a table consisting of one entry for each file. Each entry
// is of the type FILEHDR (see below).
//------------------------------------------------------------------
typedef struct
{ // 92 bytes for each file in a catalog
// this table starts at byte 0x14 in the catalog file
// there is one entry for each file in the catalog
char filename[64]; // original name of expanded file
int sizeex; // original size of expanded_file;
int sizecmp; // original size of compressed_file;
char* offset; // distance from top of file to the compressed data;
int unk1;
int unk2;
char* filelocation; // location of expanded and loaded file in memory
int unk4;
} FILEHDR;
//__declspec(dllexport) void CCat(void);
class DLLIMPORT CCat {
// data members 288 bytes
private:
char Unk[260]; // unknown maybe temp storage for compression routine?
int FileHandle; // windows assigned file handle
FILEHDR* pFileHeader; // pointer to top of FILEHDR table (probably should be public)
int FileCount; // number of files in file
int Unk1;
int Unk2;
int Unk3;
int Unk4;

public:

//
// GetFileCount
// returns number of files in current CCat
int GetFileCount(void);
//
// Open
// opens file with name pointed to by c1
// reads the FILEHDR record table from the file
// returns 0=failure 1=success
int Open(char* c1);
//
// LoadFile
// reads and decompresses file with name pointed to by c1
// from the currently open CCat
// stores the location of the decompressed file at a
// location pointed to by p1
// stores the length of the files at a location
// pointed to by u1
int LoadFile(char* c1,void** p1,unsigned long * u1);
//
// WriteFileToDisk
// writes a decompressed copy file with index i1 in the
// currently open CCat to disk into a file named c1
// i2==1 force overwrite, i2==0 disallow overwrite
int WriteFileToDisk(int i1,char* c1,int i2);
//
// LoadFile
// reads and decompresses file with index i1 in the currently open CCat
// stores the location of the decompressed file at a
// location pointed to by p1
// stores the length of the files at a location
// pointed to by u1
int LoadFile(int i1,void** p1,unsigned long * u1);
//
// FreeAll
// release all expanded files that have been loaded into memory
void FreeAll(void);
//
// Close
// closes the currently open CCat
void Close(void);
//
// FreeFile
// release file c1 from memory
int FreeFile(char* c1);
//
// FreeFile
// release file i1 from memory
int FreeFile(int i1);
//
// LoadAll
// load all file in catalog. return number of successful loads
// the pointers to each expanded file needs to be obtained from
// the FILEHDR table separately
int LoadAll(void);
//
// CCat assignment operator
CCat& operator=( const CCat& );
//
// ExpandFile
// expands a single compressed file c1
// into a single exploded file c2
// this function is unrelated to the CCat
// catalogs, and thus is static
static int ExpandFile(char* c1,char* c2);
//
// CompressFile
// compresses a single file c1
// into a single compressed file c2
// this function is unrelated to the CCat
// catalogs, and thus is static
// the newly compressed file is not openable via the Open function
static int CompressFile(char* c1,char* c2);
// probably determines if file c1 is compressed using
// the CompressFile function. Since this is static, it
// is unlikely that it is usable on the CCat catalogs
static int IsCompressed(char* c1);
//
// GetFileName
// returns a pointer to the filename of file with index i1 in the
// currently open catalog
char* GetFileName(int i1);
//
// Constructor
CCat();
//
// Destructor
~CCat(void);

protected:
//
//**GetFileHdr
// returns pointer to the file table entry for
// file c1 in the currently open CCat
FILEHDR* GetFileHdr(char* c1);
//
//**GetFileHdr
// returns pointer to the file table entry for
// file index i1 in the currently open CCat
FILEHDR* GetFileHdr(int i1);
//
//**LoadFile
// called by the other LoadFile functions.
// This is where the real action is.
int LoadFile(FILEHDR* p1);
//
//**CacheFile
// this is called from LoadFile(FILEHDR*)
// allocates space for the file to be loaded,
// and then acutually reads and decompresses the file
// and stores the location of the decompressed file into
// the filelocation slot of the current FILEHDR
int CacheFile(FILEHDR* p1);
//
//**FreeFile
// frees up memory for the file referenced by p1
int FreeFile(FILEHDR* p1);
public:
//
// CreateCatalog
// opens a dialog box for selecting files
// to be added to a new catalog file.
int CreateCatalog(void);

};

#endif /* _DLL_H_ */


Voici le prog principal:

#include "skunkcmp.h"
#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <string.h>

using namespace std;

char *c1="C:\FA-18\Wrapper\Brief.cmp";

int main(int argc, char *argv[])
{
CCat *myCCat = new CCat() ;
myCCat->Open(c1) ;
system("pause") ;
return 0;
}


Pour créer ma librairie d'importation, j'ai utilisé ce fichier .def:

obtenu avec pexport et réinjecter dans dlltool..

LIBRARY SkunkCmp.dll
EXPORTS
??0CCat@@QAE@XZ
??0CChunkFile@@QAE@XZ
??1CCat@@QAE@XZ
??1CChunkFile@@QAE@XZ
??4CCat@@QAEAAV0@ABV0@@Z
??4CChunkFile@@QAEAAV0@ABV0@@Z
?AddChunk@CChunkFile@@QAEHKKPAXKH@Z
?CheckChunkFileSize@CChunkFile@@IAEHK@Z
?Close@CCat@@QAEXXZ
?Close@CChunkFile@@QAEXXZ
?ExpandFile@CCat@@SAHPAD0@Z
?ExtendFileSize@CChunkFile@@IAEHK@Z
?FindChunk@CChunkFile@@IAEPAUCHUNKREC@@KK@Z
?FreeAll@CCat@@QAEXXZ
?FreeFile@CCat@@IAEHPAUFILEHDR@@@Z
?FreeFile@CCat@@QAEHH@Z
?FreeFile@CCat@@QAEHPAD@Z
?GetCurrentFileSize@CChunkFile@@IAEKXZ
?GetFileCount@CCat@@QAEHXZ
?GetFileHdr@CCat@@IAEPAUFILEHDR@@H@Z
?Open@CCat@@QAEHPAD@Z
?Open@CChunkFile@@QAEHPADHK@Z


Voilà mon erreur de compil:

Compilateur: Default compiler
Building Makefile: "D:\++p\TestDll\tools\dev\Makefile.win"
Exécution de make...
make.exe -f "D:\++p\TestDll\tools\dev\Makefile.win" all
g++.exe main.o -o "Skunkcmp.exe" -L"H:/DEV-CPP/lib" -L"D:/++p/TestDll/tools/dev" -lskunkcmp
main.o(.text+0x5a):main.cpp: undefined reference to `CCat::CCat()'
main.o(.text+0x6b):main.cpp: undefined reference to `CCat::Open(char*)'
Exécution terminée


Pour vérifier les noms des fonctions: j'ai même utilisé IDA pro sur la Dll en question :

??0CCat@@QAE@XZ proc near
jmp ds:__imp_??0CCat@@QAE@XZ ; __declspec(dllimport) CCat::CCat(void)
??0CCat@@QAE@XZ endp


public: int __thiscall CCat::Open(char *)
?Open@CCat@@QAEHPAD@Z proc near
jmp ds:__imp_?Open@CCat@@QAEHPAD@Z ; __declspec(dllimport) CCat::Open(char *)
?Open@CCat@@QAEHPAD@Z endp


; public: __thiscall CCat::~CCat(void)
??1CCat@@QAE@XZ proc near
jmp ds:__imp_??1CCat@@QAE@XZ ; __declspec(dllimport) CCat::~CCat(void)
??1CCat@@QAE@XZ endp


et même fait un dump ascii de la lib d'importation!!:

_?Open@CCat@@QAEHPAD@Z
__imp__?Open@CCat@@QAEHPAD@Z

etc..



Je ne vois pas du tout ce que j'ai fait comme erreur
si un expert de la DLL passe dans le coin, le bar est ouvert.....




Je pense que je vous ai fait un topo complet sur le petit projet..et je n'ai rien oublié..

Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

2

Ah, tu n'avais pas précisé que c'était du C++. sick
Tu ne peux pas linker du C++ (sauf les fonctions extern "C") entre compilateurs différents (ni même entre versions différentes du compilateur pour certains, dont g++). sad D'après le mangling des symboles, cette DLL a visiblement été compilée avec M$VC, tu ne peux pas l'utiliser avec MinGW / Dev-C++.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

cé quoi M$VC ? tu pourrais préciser...merci

Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

4

http://farrokhi.net/language/

est un outil permettant de savoir quel compilateur a été utilisé ..sur ce cas précis il donne Visual C++
Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

5

Frenchy
: cé quoi M$VC ?

Micro$oft Visual C++ smile
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

6

Je te remercie pour tes réponses précises ...
Super au moins il y a cohérence ......c'est déjà cela!!..,

ok alors pour résoudre mon prob..je dois installer Visual C++, (j' dois avoir la version 5 et/ou 6 sur CD que j'ai jamais installée!!!!)
pour garder le même principe je fais comment??

J'ai bien la procédure (que tu m'as validée!!) pour créer la librairie d'importation avec DEV-C++, mais que nenni avec Visual C++, peux tu m'indiquer comment recréer cette librairie d'importation en partant de la DLL par exemple et qu'elle soit compatible M$VC

et là à priori mes chances de faire fonctionner le prog sans erreur dans l'édition des liens devrait grandement s'améliorer..

Justement dans ce cas si j'ai une solution avec M$VC , je voudrais dans un deuxième temps pouvoir revenir complétement sur DEVC++, en fait s'il est possible de faire une interface (exe ou DLL) qui attaque la DLL en VC++..mais bon chaque chose en son temps..ne mettons pas la charrue avec euh,non avant les boeufs

sun
Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

7

Juste pour info, à part si tu t'appelles K€v¥n K¤fl€r, t'es pas obligé d'écrire M$VC et tu peux écrire MSVC comme tt le monde happy

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

8

T'as pas des convertisseurs de nom de symboles ? Parce que j'en ai déjà croisés pour les symboles des librairies statiques (pratique pour utiliser la sdl fraichement dl depuis sdkupdate sous borland).

9

Si c'était juste un problème de noms de symboles, ce serait facile, mais tout l'ABI est différente, y compris le layout des classes etc., bref tout ce qui est non-POD (c'est-à-dire autre chose que Plain Old Data) peut être géré de manière totalement différente et incompatible.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

10

Bah t'as quoi t'as la convention cdecl, le mangling qu'est différent. L'organisation des données dans la classes ne bouge pas.
Hmm, ptêt au niveau du pointeur sur la liste des fonctions virtuelles...
Enfin bon, il n'y a rien qui soit insurmontable si on connait le compilo de départ et le compilo qu'on cherche à utiliser.

11

Encore une fois, tu montres ta totale ignorance du sujet en question, et ton arrogance avec laquelle tu te présentes comme si tu savais tout. roll
spectras
: Bah t'as quoi t'as la convention cdecl,

On ne parle pas de conventions d'appel, on parle de layout de classes...
le mangling qu'est différent.

Ben oui, évidemment, mais c'est loin d'être la seule différence.
L'organisation des données dans la classes ne bouge pas.

Alors là pas du tout! Il y a des milliers (pour ne pas dire "une infinité") de manières d'organiser une classe C++ dans tous les cas non-triviaux. Par exemple: une classe A possède du padding à la fin (tail padding) pour des raisons d'alignement. Vient une classe B dérivée de A. Dans quels cas peut-on faire commencer B à l'intérieur du tail padding de A? Il y a plein de réponses différentes, et la réponse dépend fortement du compilateur en question. Et ce n'est qu'un des nombreuses différences d'ABI possibles.
Tu n'as pas l'air de te rendre compte de la complexité d'une ABI C++. Jette un coup d'œil sur l'ABI utilisée par g++ (pour toutes les plateformes, pas seulement l'Itanium) pour t'en rendre compte.
Hmm, ptêt au niveau du pointeur sur la liste des fonctions virtuelles...

Ce n'est qu'un des nombreux détails.
Enfin bon, il n'y a rien qui soit insurmontable si on connait le compilo de départ et le compilo qu'on cherche à utiliser.

En théorie, rien n'est insurmontable, en pratique, il y a tellement de différences que c'est absolument et totalement insurmontable.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

12

On ne parle pas de conventions d'appel, on parle de layout de classes...
Parce que ça en fait pas partie peut-être ? Genre tu prends VC++ par défaut il fait du cdecl. Borland lui fait du fastcall ou du stdcall si on lui dit pas le contraire.
Alors là pas du tout! Il y a des milliers (pour ne pas dire "une infinité") de manières d'organiser une classe C++ dans tous les cas non-triviaux. Par exemple: une classe A possède du padding à la fin (tail padding) pour des raisons d'alignement. Vient une classe B dérivée de A. Dans quels cas peut-on faire commencer B à l'intérieur du tail padding de A? Il y a plein de réponses différentes, et la réponse dépend fortement du compilateur en question. Et ce n'est qu'un des nombreuses différences d'ABI possibles. Tu n'as pas l'air de te rendre compte de la complexité d'une ABI C++. Jette un coup d'œil sur l'ABI utilisée par g++ (pour toutes les plateformes, pas seulement l'Itanium) pour t'en rendre compte.
Ca oui c'est la théorie. Mais en pratique, regarde l'organisation des classes générées par vc++. C'est bête et méchant :
- Les classes de base dans l'ordre où elles apparaissent
- Les données de la classe les unes après les autres. Le padding entre deux données est égal à la taille de la données suivante, dans la limite de la valeur du packing, définie par #pragma pack(). La même règle s'applique pour la classe de base dans la classe dérivée.
Je ne veux pas me montrer réducteur, mais j'ai pas non plus envie de passer en revue toute l'implémentation du compilateur de microsoft, donc je me limite à ça qui n'est qu'un exemple, et en rien la totalité de la chose (j'insiste, au cas où).
En théorie, rien n'est insurmontable, en pratique, il y a tellement de différences que c'est absolument et totalement insurmontable.
Non, faux. On ne cherche pas à surmonter toutes les différences possibles entre tous les compilateurs possibles, mais uniquement celles se présentant entre un compilateur A et un compilateur B dont on connait l'organisation des objets générés. C'est justement ça qui fait la différence entre une approche théorique pour ce problème où on regarde tout et la pratique où on ne va s'occuper que de notre cas particulier.

13

spectras
:
On ne parle pas de conventions d'appel, on parle de layout de classes...
Parce que ça en fait pas partie peut-être ? Genre tu prends VC++ par défaut il fait du cdecl. Borland lui fait du fastcall ou du stdcall si on lui dit pas le contraire.

Oui, mais cet aspect de l'ABI concerne aussi le C, et ce n'est pas de là que viennent les problèmes d'interopérabilité en C++.
Ca oui c'est la théorie.

Non, c'est la pratique pure et dure. Cette ABI est utilisée en pratique par g++, ce n'est pas de la théorie!
Mais en pratique, regarde l'organisation des classes générées par vc++. C'est bête et méchant :

1. Je ne crois pas que ce soit vraiment aussi "bête et méchant" que tu le crois.
2. Le fait que l'ABI de VC++ soit "bête et méchante" ne te sert à rien si ton deuxième compilateur est g++ avec une ABI très complexe et incompatible.
- Les classes de base dans l'ordre où elles apparaissent - Les données de la classe les unes après les autres. Le padding entre deux données est égal à la taille de la données suivante, dans la limite de la valeur du packing, définie par #pragma pack(). La même règle s'applique pour la classe de base dans la classe dérivée.

Donc le tail padding n'est pas réutilisé pour y mettre les membres de la classe dérivée? Ben, g++, lui, le réutilise, donc c'est déjà incompatible.
Je ne veux pas me montrer réducteur, mais j'ai pas non plus envie de passer en revue toute l'implémentation du compilateur de microsoft, donc je me limite à ça qui n'est qu'un exemple, et en rien la totalité de la chose (j'insiste, au cas où).

Ce n'est pas un exemple trivial (et encore, cf. ma réponse...) qui montrera les problèmes. Plus l'exemple est complexe, plus il y a de moyens de le traduire en binaire, et donc plus il y a d'incompatibilités!
En théorie, rien n'est insurmontable, en pratique, il y a tellement de différences que c'est absolument et totalement insurmontable.
Non, faux. On ne cherche pas à surmonter toutes les différences possibles entre tous les compilateurs possibles, mais uniquement celles se présentant entre un compilateur A et un compilateur B dont on connait l'organisation des objets générés.

Et ça ne te sert à rien si tu ne trouves pas de code pour le compilateur A qui donne un layout équivalent à celui du compilateur B. Et souvent, tu ne trouveras pas parce que ça n'existe pas. En C++, tu ne trouveras pas de code pour donner tous les layouts possibles.
C'est justement ça qui fait la différence entre une approche théorique pour ce problème où on regarde tout et la pratique où on ne va s'occuper que de notre cas particulier.

Détrompe-toi, même ton cas particulier peut être insoluble, ou beaucoup trop complexe pour être soluble en pratique. Tu as une vue très naïve de ce qu'est une ABI C++.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

14

Oui, mais cet aspect de l'ABI concerne aussi
le C, et ce n'est pas de là que viennent les problèmes d'interopérabilité en C++.
Donc aussi le C++.

Euh pour tous les trucs au milieu j'ai pas envie de citer le tout d'un coup, mais pour résumer : j'ai clairement dit " je me limite à ça qui n'est qu'un exemple, et en rien la totalité de la chose (j'insiste, au cas où)". N'aurais-je pas insisté suffisemment ?
Et ça ne te sert à rien si tu ne trouves pas de code pour le compilateur A qui donne un layout équivalent à celui du compilateur B. Et souvent, tu ne trouveras pas parce que ça n'existe pas. En C++, tu ne trouveras pas de code pour donner tous les layouts possibles.
Je ne vois absolument rien qui empèche par exemple d'encapsuler les accès à la classe de la dll lors de la compilation d'un programme qui veut l'utiliser ?
D'autant plus que tous les aspects ne sont pas nécessaires, vu que par exemple il est peu probable que Frenchy cherche à dériver de nouvelles classes à partir de celle existant.

15

Et bien je ne pensais pas que j'allais engendrer tout cela..mais bon les forums sont fait pour débattre..
Pour en revenir à mon problème ..be ndisons qu'en utilisant Visual C++ version 5, j'ai plus d'erreur..

donc difficile d'exploiter cela en dev-c++ ..a moins d'ecrire une espece de DLL interface..mais j'arrete là je garderais juste visual C++ pour cette partie de projet..mon but était de passer par un langage évolué car je commencais à saturer de l'assembleur!!..dommage que je ne peux le faire totalement en DEVC++ ..enfin si quelqun veut essayer je peux mettre les fichiers en ligne ou lui envoyé..cest tout petit pas plus 1mega le tout ..dll comprise
Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

16

spectras
: Euh pour tous les trucs au milieu j'ai pas envie de citer le tout d'un coup, mais pour résumer : j'ai clairement dit " je me limite à ça qui n'est qu'un exemple, et en rien la totalité de la chose (j'insiste, au cas où)". N'aurais-je pas insisté suffisemment ?

Quand le problème est que les ABIs sont complexes, prendre un exemple simple est passer totalement à côté du problème.
Et ça ne te sert à rien si tu ne trouves pas de code pour le compilateur A qui donne un layout équivalent à celui du compilateur B. Et souvent, tu ne trouveras pas parce que ça n'existe pas. En C++, tu ne trouveras pas de code pour donner tous les layouts possibles.
Je ne vois absolument rien qui empèche par exemple d'encapsuler les accès à la classe de la dll lors de la compilation d'un programme qui veut l'utiliser ?

Si tu peux prendre le compilateur avec lequel l'objet C++ a été compilé et mettre une interface C par dessus cet objet C++, alors tu as gagné. Mais ça ne marchera que dans des cas très simples. Normalement, si un objet a une interface C++, c'est parce que l'interface utilise les features C++, donc faire un binding C dessus n'est pas simple!
D'autant plus que tous les aspects ne sont pas nécessaires, vu que par exemple il est peu probable que Frenchy cherche à dériver de nouvelles classes à partir de celle existant.

Ça, tu n'en sais rien, et puis rien que les classes déjà dérivées dans l'interface sont suffisantes pour faire apparaître des problèmes dus à une ABI différente au niveau de la dérivation des classes. Et enfin, il y a aussi d'autres aspects de l'ABI qui peuvent changer, l'ABI de g++ a 22 paragraphes!
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

17

Quand le problème est que les ABIs sont complexes, prendre un exemple simple est passer totalement à côté du problème.
C'est juste citer une partie du problème. Ca ne veut pas dire qu'on ignore que ce n'est qu'une partie. Surtout quand on le marque à côté.
Si tu peux prendre le compilateur avec lequel l'objet C++ a été compilé et mettre une interface C par dessus cet objet C++, alors tu as gagné. Mais ça ne marchera que dans des cas très simples. Normalement, si un objet a une interface C++, c'est parce que l'interface utilise les features C++, donc faire un binding C dessus n'est pas simple!
Ce n'est pas simple, non. Mais ça n'est pas non plus insurmontable. L'idéal serait de faire une encapsulation C++ de la classe. Genre tu fais une classe compilée par le compilateur cible qui encapsule l'accès à la vraie classe compilée par le compilateur source.
Ça, tu n'en sais rien, et puis rien que les classes déjà dérivées dans l'interface sont suffisantes pour faire apparaître des problèmes dus à une ABI différente au niveau de la dérivation des classes. Et enfin, il y a aussi d'autres aspects de l'ABI qui peuvent changer, l'ABI de g++ a 22 paragraphes!
Je suis d'accord. Ce que je voulais dire c'est que du fait qu'on ne cherche pas à dériver la classe, il n'y a pas besoin de chercher à rendre visible à la classe encapsulée les fonctions virtuelles qui seraient surchargées en cas d'héritage, ce qui enlève quand même une grosse épine du pied.

18

Tu n'as toujours rien compris. Avoue de n'avoir rien compris au lieu de sortir une grosse bêtise après l'autre!
spectras
:
Quand le problème est que les ABIs sont complexes, prendre un exemple simple est passer totalement à côté du problème.
C'est juste citer une partie du problème. Ca ne veut pas dire qu'on ignore que ce n'est qu'une partie. Surtout quand on le marque à côté.

Ben, moi, je te dis qu'on s'en fout de ta "partie du problème", on ne peut pas résoudre le problème sans le regarder en entier!
Si tu peux prendre le compilateur avec lequel l'objet C++ a été compilé et mettre une interface C par dessus cet objet C++, alors tu as gagné. Mais ça ne marchera que dans des cas très simples. Normalement, si un objet a une interface C++, c'est parce que l'interface utilise les features C++, donc faire un binding C dessus n'est pas simple!
Ce n'est pas simple, non. Mais ça n'est pas non plus insurmontable. L'idéal serait de faire une encapsulation C++ de la classe. Genre tu fais une classe compilée par le compilateur cible qui encapsule l'accès à la vraie classe compilée par le compilateur source.

Tu n'as toujours pas compris que tu ne peux pas faire ça! Ton seul espoir est de créer une encapsulation en C pur (extern "C") avec le compilateur utilisé pour compiler ton objet. C'est le seul compilateur capable de comprendre l'ABI C++ utilisée dans ce fichier objet.
Ça, tu n'en sais rien, et puis rien que les classes déjà dérivées dans l'interface sont suffisantes pour faire apparaître des problèmes dus à une ABI différente au niveau de la dérivation des classes. Et enfin, il y a aussi d'autres aspects de l'ABI qui peuvent changer, l'ABI de g++ a 22 paragraphes!
Je suis d'accord.

Et pourtant tu continues à dire le contraire juste en dessous.
Ce que je voulais dire c'est que du fait qu'on ne cherche pas à dériver la classe,

Mais qui te parle de dériver la classe???
Essaye de satisfaire tous les 22 paragraphes pour la classe en cours et reviens quand tu as fini!
Et l'ABI de dérivation de classe intervient aussi si tu as une classe A et une classe B dérivée de A dans ton fichier objet, et que tu veux utiliser cette classe B avec l'autre compilateur. C'est déjà impossible dans pas mal de cas.
il n'y a pas besoin de chercher à rendre visible à la classe encapsulée les fonctions virtuelles qui seraient surchargées en cas d'héritage, ce qui enlève quand même une grosse épine du pied.

Mais ça ne te sert à rien parce que même le layout de la classe ne correspond pas. Et au cas où tu ne saches pas ce qu'est un layout de classe (ce qui est probablement le cas vu ton ignorance poussée), ce sont tous les offsets entre les représentations binaires des membres de la classe, et dans certains cas même la taille et le format de ces représentations.

Et sache que contrairement à toi, je ne tire pas cela des cheveux. Tous les mainteneurs de g++ et MinGW disent la même chose que moi, demande sur leurs mailing lists si tu ne me crois pas.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

19

avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

20

Bon écoute, jusqu'à maintenant je me suis retenu mais je vais me permettre un petit interlude distryant :
Encore une fois, tu montres ta totale ignorance du sujet en question, et ton arrogance avec laquelle tu te présentes comme si tu savais tout. roll
Tu n'as toujours rien compris. Avoue de n'avoir rien compris
au lieu de sortir une grosse bêtise après l'autre!
(ce qui est probablement le cas vu ton ignorance poussée)
rotfl (et encore je dois en avoir oublié)
Bon, cet entracte jubilatoire passé, reprenons.
Ben, moi, je te dis qu'on s'en fout de ta "partie du problème", on ne peut pas résoudre le problème sans le regarder en entier!
Bon, faisons les choses de façon rationnelle : admettons que le problème que l'on appellera P corresponde à un ensemble de sous problèmes S0, S1, ..., Sn. J'ai dit : S1 et S4 font partie du problème P. Je n'ai absolument pas dit que {S1, S4} formaient une partition de P.
Tu n'as toujours pas compris que tu ne peux pas faire ça! Ton seul espoir est de créer une encapsulation en C pur (extern "C") avec le compilateur utilisé pour compiler ton objet. C'est le seul compilateur capable de comprendre l'ABI C++ utilisée dans ce fichier objet.
Mais le compilateur n'a pas besoin de la comprendre. C'est l'implémentation de l'objet d'encapsulation qui la comprend. Je te ferai un joli schéma si tu veux (bah oué il parait que je suis arrogant alors je peux me permettre de dire çà).
Mais ça ne te sert à rien parce que même le layout de la classe ne correspond pas
Justement.

21

spectras
:
Ben, moi, je te dis qu'on s'en fout de ta "partie du problème", on ne peut pas résoudre le problème sans le regarder en entier!
Bon, faisons les choses de façon rationnelle : admettons que le problème que l'on appellera P corresponde à un ensemble de sous problèmes S0, S1, ..., Sn. J'ai dit : S1 et S4 font partie du problème P. Je n'ai absolument pas dit que {S1, S4} formaient une partition de P.

Mais comme la réunion des problèmes que tu as résolus ne donne pas P, résoudre ces problèmes ne résout pas P. Donc ta "solution" ne sert à rien.
Tu n'as toujours pas compris que tu ne peux pas faire ça! Ton seul espoir est de créer une encapsulation en C pur (extern "C") avec le compilateur utilisé pour compiler ton objet. C'est le seul compilateur capable de comprendre l'ABI C++ utilisée dans ce fichier objet.
Mais le compilateur n'a pas besoin de la comprendre. C'est l'implémentation de l'objet d'encapsulation qui la comprend. Je te ferai un joli schéma si tu veux (bah oué il parait que je suis arrogant alors je peux me permettre de dire çà).

Vas-y, fais ton schéma pour que je rigole... Tu penses sérieusement que les mainteneurs de g++ et du portage MinGW n'auraient pas pensé à ton petit schéma avant de sortir les déclarations que je t'ai indiquées?
Mais ça ne te sert à rien parce que même le layout de la classe ne correspond pas
Justement.

Justement non. Je te dis que le layout ne correspond pas, je te dis même pourquoi il ne correspond pas, et je te donne des exemples concrets pour lesquels il ne correspond pas, je fournis aussi des citations de personnes respectées dans le domaine disant que le layout ne correspond pas, mais non, monsieur spectras continue à affirmer qu'il correspond. roll
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

22

Mais comme la réunion des problèmes que tu as résolus ne donne pas P, résoudre ces problèmes ne résout pas P. Donc ta "solution" ne sert à rien.
Je n'ai jamais dit que c'était une solution, j'ai même insisté, et lourdement il me semble, sur le fait que ça ne représente pas la totalité du problème :
"Parce que ça en fait pas partie peut-être ?"
"qui n'est qu'un exemple, et en rien la totalité de la chose (j'insiste, au cas où)"
"Je n'ai absolument pas dit que {S1, S4} formaient une partition de P."
Vas-y, fais ton schéma pour que je rigole...
"Encore une fois, tu montres ta totale ignorance du sujet en question, et ton arrogance avec laquelle tu te présentes comme si tu savais tout. roll"
Tu penses sérieusement que les mainteneurs de g++ et du portage MinGW n'auraient pas pensé à ton petit schéma avant de sortir les déclarations que je t'ai indiquées?
Je pense surtout que ce qu'ils cherchent à faire est différent du problème qui nous occupe, car ils cherchent une solution générique tandis qu'ici nous avons pour seul objectif l'accès à une classe spécifique (que en plus nous pouvons examiner pour voir comment elle est implémentée).
fais ton schéma
Ca donne un truc comme ça.
schemaabiwrap.png
Justement non. Je te dis que le layout ne correspond pas, je te dis même pourquoi il ne correspond pas, et je te donne des exemples concrets pour lesquels il ne correspond pas, je fournis aussi des citations de personnes respectées dans le domaine disant que le layout ne correspond pas, mais non, monsieur spectras continue à affirmer qu'il correspond.roll
Es-tu sûr de bien avoir saisi le sens du mot "justement" ?

23

juste une question comme cela pourquoi ne pas appliquer cela sur mon problème, là au moins c'est du concret car là j'avoue être perdu dans vos commentaires...Ca plane un peu haut pour moi ...
Pour résumer très schématiquement, vus n'êtes pas d'accord, en disant pour l'un:

pas possible d'attaquer une librairie C++ d'un compilateur X avec un outil Y

et pour l'autre si c'est possible..car en gros rien n'est impossible..

je ne veux offenser ni l'un ni l'autre mais je voulais juste résumer le débat...



Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

24

Oué à peu près. Kévin dit qu'il est impossible pour ue compilateur Y de comprendre et de lier une classe dans un objet compilé par un compilateur X. Ca c'est indéniable.
Ce que je propose c'est d'implémenter dans une classe d'encapsulation l'accès à l'objet binaire contenant la classe généré par le compilateur X. Cette classe d'encapsulation étant bien évidemment compilée par le compilateur Y, pour permettre à un programme compilé par Y de l'utiliser.

Voilà c'est ce à quoi correspond le schéma que j'ai mis au dessus. (X c'est le compilo source et Y le compilo cible)

25

Bah, je ne peux que dire: amuse-toi bien avec ce hack grossier (parce que c'est bien ce que c'est). À mon avis, tu n'iras pas loin. Si l'ABI en question est représentable en C pur (ce qui n'est pas garanti non plus), tu peux y arriver. Sinon, il faudra en plus t'amuser avec de l'assembleur inline. Mais si tu penses y arriver, pourquoi ne le fais-tu pas pour la classe concrète de Frenchy? Au moins ça servirait à quelque chose...
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

26

Mais si tu penses y arriver, pourquoi ne le fais-tu pas pour la classe concrète de Frenchy? Au moins ça servirait à quelque chose...


Ca sur ce point kevin tu as raison...etant originaire du nord de la france,
dans ma région on dit
"y a les grands diseux et les grands faiseux..."

dehors

passez un bon weekend!!

Ps je tiens les fichiers a dispo...

Mais bon je suis arrivé à contourner le problème en utilisant le compilateur qui avait créé la lib. (MSVC 5) et ce qui est le plus important pour moi
Frenchy
TSH Team
Développeur F18 jane's - vieux jeux

27

Bah, je ne peux que dire: amuse-toi bien avec ce hack grossier (parce que c'est bien ce que c'est). À mon avis, tu n'iras pas loin. Si l'ABI en question est représentable en C pur (ce qui n'est pas garanti non plus), tu peux y arriver. Sinon, il faudra en plus t'amuser avec de l'assembleur inline. Mais si tu penses y arriver, pourquoi ne le fais-tu pas pour la classe concrète de Frenchy? Au moins ça servirait à quelque chose...
- Eh j'ai pas dit que c'était propre, mais d'un autre côté pour faire les choses complètement propres faudrait avoir le code source, donc on fait avec les moyens du bord.
- J'ai pas que ça à faire. Y'a pas mal de boulot et je fais autre chose de mon temps (d'autant plus que Frenchy a déjà une autre solution qui lui convient. comme on dit, je propose, il dispose).
- Merci d'avoir pris la peine de considérer la proposition que je faisais depuis le post 13. J'avoue que je commençais à désespérer que tu la prennes un jour en considération.