IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

DLL C++ -> Delphi


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Analyse système
    Inscrit en
    Mai 2013
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 190
    Par défaut DLL C++ -> Delphi
    Bonjour tout le monde,

    voilà le problème, j'ai une DLL écrite en C++ et que j'aimerai intégrer sous Delphi (j'utilise donc des liaisons dynamiques).

    Comme prévu, je ne peux que capter des fonctions ou des procédures ne faisant pas appel à d'autre appel de fonction, du style :

    Je peux capter une simple fonction :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    BYTE Classe::Function(void)
    {
    	BYTE	by_truc	= 0;
    	BYTE *	pby_truc		= 0;
    	WORD	w_value_len		= 0;
     
    	if (w_value_len >= 2)
    	{
    		by_output_nb = (pby_value[1] & 0x0F) * 4;
    	}
    	return by_output_nb;
    }

    Par contre une fonction qui appelle d'autre fonction, là j'ai une "violation d'accès" :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    BYTE Classe::Function(void)
    {
    	BYTE	by_truc	= 0;
    	BYTE *	pby_truc		= Valeur();
    	WORD	w_value_len		= Longueur();
     
    	if (w_value_len >= 2)
    	{
    		by_output_nb = (pby_value[1] & 0x0F) * 4;
    	}
    	return by_output_nb;
    }

    Donc je sais qu'il faudrait "mapper" tout ça mais les exemples sont rares sur le net, alors si jamais quelqu'un à un exemple tout bête à me proposer je serai très content

    Merci pour vos réponses d'avance en tout cas !
    Greg

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    les objets C++ placés dans une DLL publient leurs méthodes, il est donc possible de les lier dans une application Delphi. Mais ce que la DLL ne fourni pas c'est la structure de la classe et tout le code présent dans le .h

    l'approche classique est de créer un wrapper C pour l'objet C++, ce qui nécessaire un peu de développement en C.

    ensuite il est théroriquement possible de créer le wrapper sous Delphi mais c'est loin d'être facile et ce n'est surtout pas automatique.

    à l'époque de Kylix j'avais fait des tests sur QT sous Linux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    const
     qt='libqt.so';
     
    procedure Create_QApplication(this,argc,argv:pointer); cdecl external qt name '__12QApplicationRiPPc';
    procedure Destroy_QApplication(this:pointer); cdecl external qt name '_._12QApplication';
    procedure QApplication_setMainWidget(this,Widget:pointer); cdecl external qt name 'setMainWidget__12QApplicationP7QWidget';
    procedure QApplication_exec(this:pointer); cdecl external qt name 'exec__12QApplication';
    après toute la question est de savoir ce que l'on met dans "this" dont la structure est déclarée dans un .h, c'est la structure de l'objet C++ avec la table de méthodes virtuelles etc....

    le fruit des mes recherches de l'époque se trouve ici

    pour construire ce code j'avais utilisé des petites applications C qui me donnaient à coup de sizeof() et de pointeurs le format des structures...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre confirmé
    Homme Profil pro
    Analyse système
    Inscrit en
    Mai 2013
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 190
    Par défaut
    Bien en effet, je me doutais que cela n'était pas aussi facile mais bon je dois quand même le faire ! :p
    Merci pour tes sources en tout cas, est-ce que par hasard il te reste de la doc sur comment construire un wrapper en C etc ... ?

    Bonne journée !

  4. #4
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    un wrapper c'est tout bête, en voici un sous Delphi avec TForm pour comprendre le principe, ensuite il "suffit" de faire la même chose en C pour l'objet C++

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    function CreateForm: THandle;
    var
      Form: TForm1;
    begin
      Form := TForm1.Create(Application);
      Result := THandle(Form);
    end;
     
    procedure ShowForm(Handle: THandle);
    begin
      TForm(Handle).Show();
    end;
     
    procedure SetCaptionForm(Handle: THandle; Caption: PChar);
    begin
      TForm(Handle).Caption := Caption;
    end;
     
    procedure FreeForm(Handle: THandle);
    begin
      TForm(Handle).Free;
    end;
    toutes les méthodes sont transformées en fonctions avec un paramètre opaque "Handle" qui est en fait un pointeur sur l'instance de classe.

    la DLL expose de simples fonctions et c'est le wrapper qui se charge d'instancier, libérer, de résoudre les méthodes virtuelles etc...bref tous les concepts objets.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre confirmé
    Homme Profil pro
    Analyse système
    Inscrit en
    Mai 2013
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyse système
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 190
    Par défaut
    Ok donc par exemple :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    class Test
    {
      public:
        Test();
        void getHello(char * &AString); 
    };
     
    Test::Test()
    {
    }
     
    void Test::getHello(char * &AString)
    {
      const char * str = "Hello World from C++";
      strcpy(AString, str);
    }
     
    extern "C"{ // j'exporte pour le C
      void createTestInstance(void * &instance)
      {
        instance = new Test(); // je créé l'instance
      }
     
      void doHello(void * instance, char * &AString)
      {
        Test * lInstance = (Test *) instance; // Je passe la fonction en paramètre comme pointeur
        lInstance->getHello(AString);
      }
     
      void deleteTestInstance(void  * instance)
      {
        delete (Test *)instance; // et mon desctructeur 
        instance = NULL;
      }
    }

    Et bien j'ai pas fini car j'ai une sacrée grosse DLL sous la main ... ^^

  6. #6
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Citation Envoyé par phoenixgreg Voir le message
    Et bien j'ai pas fini car j'ai une sacrée grosse DLL sous la main ... ^^
    oui c'est le principal problème

    ceci dit tu peux alléger le code en trichant sur les déclarations qui ne changeront strictement rien à l'API...exemple sous Delphi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    function CreateForm: TForm1;
    begin
      Result := TForm1.Create(Application);
    end;
     
    procedure ShowForm(Form: TForm);
    begin
      Form.Show();
    end;
     
    procedure SetCaptionForm(Form: TForm; Caption: PChar);
    begin
      Form.Caption := Caption;
    end;
     
    procedure FreeForm(Form: TForm);
    begin
      Form.Free;
    end;
    on garde la notion de Handle uniquement sur l'importation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function CreateForm: THandle; external 'madll.dll';
    procedure ShowForm(Handle: THandle); external 'madll.dll';
    procedure SetCaptionForm(Handle: THandle; Caption: PChar); external 'madll.dll'; 
    procedure FreeForm(Handle: THandle); external 'madll.dll';
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. dll c++ et delphi
    Par poussinphp dans le forum Langage
    Réponses: 8
    Dernier message: 17/08/2005, 19h30
  2. appel DLL C++ en Delphi (pb avec type)
    Par fkerbourch dans le forum Langage
    Réponses: 7
    Dernier message: 11/07/2005, 17h31
  3. Comment créer une dll Win32 sous Delphi ?
    Par Mickey.jet dans le forum Langage
    Réponses: 8
    Dernier message: 16/06/2005, 15h38
  4. [VB6]Passage d'un tableau dans une DLL écrite en delphi
    Par flash dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 20/09/2002, 10h15
  5. Utilisation d'une dll écrite en delphi 5 dans VB6
    Par Jean-Louis dans le forum Langage
    Réponses: 4
    Dernier message: 05/08/2002, 09h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo