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

Langage Delphi Discussion :

DLL extern C


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut DLL extern C
    Bonjour tout le monde,

    Je suis en train de faire un wrapper en C++ avec les points d'entrées en C (extern C) pour que Delphi "comprenne" les paramètres.
    Sauf que je tombe sur un os, car cette fonction ci-dessous demande un pointeur de classe "CComBase *po_com" et je ne vois pas comment Delphi peux comprendre cela.

    Donc je sais qu'il faut le construire "à la volée" mais je n'ai pas d'indice ...

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    extern "C" {
    	CReseauHandle __declspec(dllexport) __cdecl NewCReseau(CComBase *po_com, 
    			PFCT_MESS_MANAGER pfct_message_manager, 
    			void *pv_owner, 
    			const BYTE *pby_address_sop_locale = NULL, 
    			DWORD dw_flags = DEFAULT_FLAGS)
    	{
    		return new CReseau(po_com,pfct_message_manager,pv_owner, 
    			 pby_address_sop_locale,dw_flags);				
    	}
    }

    Cette fonction créée l'instanciation de ma classe CReseau.

    Comment puis-je faire pour que Delphi comprenne le paramètre "CComBase *po_com" (pointeur de classe) ?

    Forcément j'ai une violation d'accès avec la dll qui découle de ce code.

    Merci pour votre aide en tout cas.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 456
    Points : 24 868
    Points
    24 868
    Par défaut
    Tu ne peux pas échanger des classes C++ vers le Delphi, il faut transformer cela soit en struct type WinAPI ou en interface OLE

    Si tu fais le Wrapper en Visual C++, je te conseille d'utiliser soit :
    - struct aligné à 0 côté C++ et packed record côté Delphi, tu seras sûr que l'alignement sera toujours en phase des deux côtés
    - interfaces OLE, en C++ tu produis un objet COM OLE, c'est fiable, c'est juste qu'il faut l'installer et donc rend le déploiement plus pénible

    Si c'est du C++Builder, tu peux même faire un BPL qui contient ton composant Wrapper et utiliser ce composant dans Delphi
    Tu peux aussi utiliser struct ou interface
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Merci beaucoup ShaiLeTroll, tes réponses sont toujours très efficaces, je n'ai pas le choix que de me tourner vers struct type WinAPI car j'utilise VS en C++.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 456
    Points : 24 868
    Points
    24 868
    Par défaut
    Sinon ta classe CComBase faudra regarder si ce n'est pas lié à une interface IDispatch ou IUnknown dans le code C++ car c'est juste du COM OLE
    Vérifie si CComBase contient une méthode _AddRef() et _Release()
    Si oui, c'est donc bien du COM et cela correspond au TComObject du Delphi
    Tu dois pouvoir traduire les interfaces C++ en Delphi
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    class CComBase : public IComParameter, public CObject
    {

    }

    Non on ne travail pas avec du COM (oui ça aurait été plus simple avec Delphi du coup).

    je ne m'attendais pas à devoir transformer les classes demandées en type struct, car il y en a beaucoup forcément :p

  6. #6
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Après le truc c'est que cette classe hérite, et le struct je ne sais pas si il aime trop ça. Donc même si je m'embête à transformer toutes mes classes au final je ne sais pas si ça va fonctionner comme sur des roulettes.

  7. #7
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Ne puis-je pas tout "simplement" m'occuper de la déclaration de ce pointeur de classe du côté C++ juste avant le return new ? Et avec Delphi passer en paramètre tous les autres

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 456
    Points : 24 868
    Points
    24 868
    Par défaut
    Oui, le struct sera juste pour exposer les données utiles à Delphi, pas d'héritage, pas de type complexe, faut se limiter au struct du C

    Tu peux assimiler ton pointeur à un Handle sans que Delphi ne sache ce qu'il contient, cela fonctionnera aussi
    THandle, Pointer, NativeUInt ... tout ce qui peut contenir un identifiant mémoire 32/64 bits
    Si 32Bits, DWORD est possible aussi

    En fait CReseauHandle c'est surement le même principe qu'il faut appliquer à CComBaseHandle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    type
      CComBaseHandle: Pointer;
      PFCT_MESS_MANAGER ...
     
    function NewCReseau(po_com: CComBaseHandle; pfct_message_manager: PFCT_MESS_MANAGER, pv_owner: Pointer, pby_address_sop_locale: PByte; dw_flags: DWORD): CReseauHandle;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par phoenixgreg Voir le message
    Bonjour tout le monde,

    Je suis en train de faire un wrapper en C++ avec les points d'entrées en C (extern C) pour que Delphi "comprenne" les paramètres.
    Sauf que je tombe sur un os, car cette fonction ci-dessous demande un pointeur de classe "CComBase *po_com" et je ne vois pas comment Delphi peux comprendre cela.

    Donc je sais qu'il faut le construire "à la volée" mais je n'ai pas d'indice ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    extern "C" {
    	CReseauHandle __declspec(dllexport) __cdecl NewCReseau(CComBase *po_com, 
    			PFCT_MESS_MANAGER pfct_message_manager, 
    			void *pv_owner, 
    			const BYTE *pby_address_sop_locale = NULL, 
    			DWORD dw_flags = DEFAULT_FLAGS)
    	{
    		return new CReseau(po_com,pfct_message_manager,pv_owner, 
    			 pby_address_sop_locale,dw_flags);				
    	}
    }
    Cette fonction créée l'instanciation de ma classe CReseau.

    Comment puis-je faire pour que Delphi comprenne le paramètre "CComBase *po_com" (pointeur de classe) ?

    Forcément j'ai une violation d'accès avec la dll qui découle de ce code.

    Merci pour votre aide en tout cas.
    et bien il faut que ton Wrapper wrappe aussi CComBase avec une fonction NewCComBase() dont le résultat sera en paramètre de NewCReseau
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Mais c'est bien sûr, je vais mettre cela en pratique demain, ça devrait le faire !

    Merci les gens !

  11. #11
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Arf je tombe sur un os :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CComBaseHandle LIBCOMHSL_API NewCComBase(IN DWORD dw_TimOutAckEmi, IN DWORD dw_NbRetry, IN DWORD dw_TimOutEmi, IN DWORD dw_TimOutAckRec, IN DWORD dw_ScanDelay)
    	{
     
    		return new CComBase(dw_TimOutAckEmi, dw_NbRetry, dw_TimOutEmi, dw_TimOutAckRec, dw_ScanDelay);
    	}

    CComBase est une classe abstraite; comment puis-je faire son instanciation du coup ?
    Si j'enlève "new" il me dit que "type name is not allowed" :s

    Il me manque plus que ce mystère pour que je puisse enfin coder tranquillement grrrr ...

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    c'est que tu dois avoir des classes dérivées de CComBase et ce sont elles qu'il faut wrapper.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  13. #13
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Absolument je viens de wrapper les classes dérivées, il y en a juste une qui me pose problème :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CSopkeSADData ();
    	CSopkeSADData (const CSopkeSADData &ro_sopke_sad_data);
    	CSopkeSADData (E_ENCRYPTION			e_encryption,
    				   IN BYTE *			pby_ansi931_key,
    				   IN BYTE *			pby_prf_key,
    				   IN BYTE *			pby_ansi931_vector,
    				   IN BYTE *			pby_mid,
    				   IN BYTE *			pby_sik,
    				   IN BYTE *			pby_user_shared_key,
    				   IN E_SOPKE_MODULE	e_sopke_module, 
    				   IN BOOL				b_initiator);

    quand je fais :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    po_sopke_sad_data = new CSopkeSADData ();

    il me met une erreur sur le "CSopkeSADData " qui dit : "no appropriate default constructor available", alors qu'il y a bien un constructeur sans paramètre dans le lot Oo"

    Je commence à avoir ce qu'il me faut, c'est vraiment pas évident de passer une DLL C++ vers Delphi mon dieu ..

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    tu rencontres plus là un problème avec les objets C++...

    mais as-tu réellement besoin de publier tous ces objets ? ne peux tu pas faire une API simplifiée en C ?

    je ne sais pas si c'est possible, mais par exemple , pour parler en termes Delphi, je n'ai pas besoin de publier tous les objets Indy pour créer une DLL qui me permette de faire une requête Web, je peux très bien me contenter d'une fonction qui accepte une URL en entrée et retourne un PChar en sortie. Toute la partie objet reste au niveau de la DLL.

    l'autre solution serait aussi de passer par des Interface ou même des Objets COM, je ne sais pas faire ça en C++ mais c'est peut-être une approche plus simple côté Delphi.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  15. #15
    Membre régulier
    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
    Points : 113
    Points
    113
    Par défaut
    Bien déjà un grand merci à vous tous, je n'aurai pas réussi sans vous.

    La dernière erreur était du au fait qu'il me manquait un header non déclaré ...

    Donc pour ceux que ça intéresse voici un exemple de "comment j'ai wrappé des classes en C++ pour les transformer en fonction 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
    24
    25
    26
     
    extern "C" {
            // Le prototype de ma classe CReseau, vu qu'il me faut passer un objet en paramètre "CComSerie *po_com", il faut que j'instancie cette classe avant 
    	CReseauHandle __declspec(dllexport) __cdecl NewCReseau(CComSerie *po_com, 
    			PFCT_MESS_MANAGER pfct_message_manager, 
    			void *pv_owner, 
    			const BYTE *pby_address_sop_locale = NULL, 
    			DWORD dw_flags = DEFAULT_FLAGS)
    	{
    		// Instanciation de la classe CComSerie, ce qui est retourné est passé en paramètre dans la classe CReseau, si CComSerie est une classe abstraite, wrappé une autre classe qui en hérite
    		CComSerie* CComSerieHandle = new CComSerie(
    		by_port_number
    		,dw_TimOutAckEmi 	= MS_DW_TIMEOUT_ACQ_EMISSION
    		,dw_NbRetry 		= MS_DW_NB_RETRY
    		,dw_TimOutEmi 	= MS_DW_TIMEOUT_EMISSION
    		,dw_TimOutAckRec 	= MS_DW_TIMEOUT_ACQ_RECEPTION
    		,dw_ScanDelay 	= MS_DW_SERIAL_SCAN_DELAY);
                    // po_com s'approprie l'instance de classe CComSerie
    		po_com = CComSerieHandle;
     
                    // Je peux du coup le passer en paramètre
     
    		return new CReseau(po_com,pfct_message_manager,pv_owner, 
    			 pby_address_sop_locale,dw_flags);				
    	}
    }
    Du côté Delphi maintenant :

    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
     
    interface
     
    uses
      SysUtils;
     
    type
    CReseauHandle = Cardinal;
    CComBaseHandle = Pointer;
     
    / Static Link
    function NewCReseau(po_com:CComBaseHandle;pfct_message_manager:integer;const pv_owner: Pointer;const pby_address_sop_locale:PByte;dw_flags:WORD): CReseauHandle; cdecl;
     
    implementation
     
    const
      DLLName = 'Lib.dll';
      function NewCReseau; external DLLName name 'NewCReseau';
     
    end.
    Voilà j'espère que ça pourra aider quelqu'un d'autre.
    Si vous avez des suggestions n'hésitez pas et merci encore

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

Discussions similaires

  1. JNI/DLL - Extern C : Généralisation ?
    Par ni0urk dans le forum MFC
    Réponses: 1
    Dernier message: 19/01/2006, 08h27
  2. Appel aux fonctions d'une DLL externe ??
    Par Fbartolo dans le forum Access
    Réponses: 7
    Dernier message: 21/11/2005, 17h54
  3. dll ActiveX utilisant une DLL externe
    Par Metal3d dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 10/11/2005, 18h02
  4. [Jonas]Ajout de dll externes
    Par romainp22 dans le forum JOnAS
    Réponses: 8
    Dernier message: 14/01/2005, 11h41
  5. Dialogue DLL externe
    Par rgarnier dans le forum XMLRAD
    Réponses: 8
    Dernier message: 07/05/2003, 14h28

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