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

C# Discussion :

Objet Com C# réutilisé en delphi [Débutant]


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Points : 25
    Points
    25
    Par défaut Objet Com C# réutilisé en delphi
    Bonjour,

    je dois, pour mon travail, écrire du code c# et pouvoir utiliser les methodes dans un programme delphi. J'esperais dans un premier temps faire une dll mais j'ai cru comprendre que ce n'etait pas possible. Je précise que je débute totalement en C#, je traine depuis plusieurs heures sur les forums/tutoriels pour tenter de faire un objet com tout simple mais bien entendu ca ne marche pas.
    J'ai créé un nouveau projet en tant que "Bibliotheque de classes" et j'ai le code tout simple suivant (dans un premier temps je veux juste faire fonctionner un truc simplissime, je verrai le reste plus tard):
    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
     
    using System;
     
    namespace testDll
    {
        public class Human
        {
            int age;
            public int Age { get { return age; } set { age = value; } }
     
            public Human()
            {
                age = 0;
            }
     
            public void Anniversaire()
            {
                age++;
            }
        }
     
    }
    J'ai bien coché "Inscrire pour COM Interop" et j'ai bien modifié la valeur [assembly: ComVisible(true)] dans AssemblyInfo.cs

    A la génération, j'ai bien un fichier tlb que je peux importer dans delphi, mais si je peux instancier un objet Human, je n'ai pas accès ni à la proriété age ni à la methode Anniversaire:

    Est ce que quelqu'un pourrait m'éclairer sur la (ou plus certainement les) erreur(s) commise(s).
    Merci d'avance

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Salut,

    Il faut ajouter les attributs à ta classe Human :
    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
    using System;
     
    namespace testDll
    {
        [ComVisible(true), GuidAttribute("CD2FFCBB-7C61-4a46-A8CD-763D3402745F")]
        [ProgId("testDll.Human")]
        public class Human
        {
            int age;
            public int Age { get { return age; } set { age = value; } }
     
            public Human()
            {
                age = 0;
            }
     
            public void Anniversaire()
            {
                age++;
            }
        }
    }

    Je ne sais plus si il est nécessaire de signer la dll. A tester si tu vois que ça ne suffit pas

  3. #3
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut exposer une classe com ,ne pas exposer l'interface
    bonjour pixigol
    Il est preferable d'exposer ta classe com par le biais d'une interface,sans pour autant publier l'interface pour eviter que les gens modifient ta classe plus tard en implement une autre forme de classe.
    Pour cela :
    -declare une interface InterfaceHuman avec attribut InterfaceIsIDispatch.
    -declare ta classe Human qui implement l' interface InterfaceHuman avec attribut ClassInterface(ClassInterfaceType.None).
    -implemente ta classe Human
    Utilise l'outils GuidGen de vs pour recreer tes 3 numeros "Guid" dans :
    Outils ->Create GUID->New GUID ->copy et paste dabs l'editeur VS trois fois
    (interface InterfaceHuman,EventsHuman et class Human).

    Pour -deboguer seulement sur ta machine- n'oublies de cocher Inscrire pour Com Interop.
    L'inscription sur machine user se fait avec l'utilitaire Regasm.exe de VS.

    Voici le code de ta classe Human :

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    //rappel   guide MSDN
    //L'exposition d'objets Visual C# à COM requiert la déclaration d'une interface de classe, d'une interface d'événement, si elle est requise, et de la classe elle-même. Les membres de la classe doivent se conformer aux règles suivantes pour être visibles par COM : 
    //La classe doit être publique.
    //Les propriétés, les méthodes et les événements doivent être publics.
    //Les propriétés et les méthodes doivent être déclarées sur l'interface de classe.
    //Les événements doivent être déclarés dans l'interface d'événements.
    //NB:Les autres membres publics de la classe qui ne sont pas déclarés dans ces interfaces ne seront pas visibles pour COM, 
    //mais seront visibles pour d'autres objets .NET Framework.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
     
    namespace testDll
    {
     
        //Pour exposer des propriétés et des méthodes à COM, vous devez les déclarer dans l'interface de classe,
        //les marquer avec l'attribut DispId et les numeroter progressivement et les implémenter dans la classe.
        //L'ordre dans lequel les membres sont déclarés dans l'interface est l'ordre utilisé pour la vtable COM.
     
        [ComVisible(true)]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        //Recreer S.V.P ce GUID avec utilitaire GuidGen dans Outils.
        [Guid("B7047F1B-A70D-4352-91E3-D95464A63EC0")]
        public interface InterfaceHuman
        {
            [DispId(1)]  int Age { get; set;}
            [DispId(2)]  void Anniversaire();
        }
        //Pour exposer des événements à partir de votre classe, 
        //vous devez les déclarer sur l'interface d'événements et les marquer avec un attribut DispId. 
        //nb:La classe ne doit pas implémenter cette interface. 
        // 
        [ComVisible(true)]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        //Recreer S.V.P ce GUID avec utilitaire GuidGen dans Outils.
        [Guid("0B1F9044-8E79-48ef-BE2A-D199DB77DC39")]
        public interface EventsHuman
        {
        }
     
        //Recreer S.V.P ce GUID avec utilitaire GuidGen dans Outils.
        [ComVisible(true), Guid("75917281-4FEC-435d-AA05-EF86D7DCC5AB"),
            ClassInterface(ClassInterfaceType.None),
            ComSourceInterfaces(typeof(EventsHuman))]
        [ProgId("testDll.Human")]
        //Declaration de la Classe Human et d'autres classes si tu veux............
        //qui implementent ton interface InterfaceHuman
        public class Human : InterfaceHuman
          {
     
            public Human()
            {
                age = 20;
            }
            //ici les prop et methodes visibles uniquement à .Net
            //Net non visible à com
            int ageNet; 
            public int AgeNet { get { return ageNet; } set { ageNet = value; } }
     
            public void AnniversaireNet()
            {
                age++;
            }
            //
            //ici les prop et methodes visibles  à com
            //
            #region InterfaceHuman Membres
            //implement prop int Age 
            int age; 
            public int Age { get { return age; } set { age = value; } }
     
            //implement methode Anniversaire 
            public void Anniversaire()
            {
                age++;
            }
            #endregion
          }
     
    }
    bon code................

  4. #4
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci beaucoup pour vos réponses, je teste ça ce matin!

  5. #5
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Ca marche super bien... sur mon poste.

    Je vous décris ce que j'ai fait, peut-être que mon erreur est grossiere.

    J'ai suivi les conseils décrites par MABROUKI, et j'ai importé le tlb dans delphi. Je retrouve bien d'ailleurs cette portion de code dans le .pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
      LIBID_testDll: TGUID = '{E8BCA46F-8FE8-4EF0-8FA8-78971244AE99}';
     
      DIID_InterfaceHuman: TGUID = '{53809E49-B585-4FBC-9243-2ED2101E4366}';
      DIID_EventsHuman: TGUID = '{2AF1E740-297C-4E2D-94A9-7AA654CF8A81}';
      CLASS_Human: TGUID = '{71A99D26-0218-4601-B7E6-D3061B630EFD}';
    Je retrouve bien ces entrées dans MA base de registre (créée si j'ai bien compris à la compilation grace à la coche "inscrire pour COM Interop". Là ou ca s'est corsé, c'est pour tester sur un autre poste. J'ai utilisé la commande regasm /regfile et j'ai bien obtenu un .reg. J'ai été chagriné quand je l'ai ouvert de voir que je ne retrouvais pas toutes mes entrées correspondant à "mes TGUID" :

    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
    27
    28
     
    REGEDIT4
     
    [HKEY_CLASSES_ROOT\testDll.Human]
    @="testDll.Human"
     
    [HKEY_CLASSES_ROOT\testDll.Human\CLSID]
    @="{71A99D26-0218-4601-B7E6-D3061B630EFD}"
     
    [HKEY_CLASSES_ROOT\CLSID\{71A99D26-0218-4601-B7E6-D3061B630EFD}]
    @="testDll.Human"
     
    [HKEY_CLASSES_ROOT\CLSID\{71A99D26-0218-4601-B7E6-D3061B630EFD}\InprocServer32]
    @="mscoree.dll"
    "ThreadingModel"="Both"
    "Class"="testDll.Human"
    "Assembly"="testDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    "RuntimeVersion"="v2.0.50727"
     
    [HKEY_CLASSES_ROOT\CLSID\{71A99D26-0218-4601-B7E6-D3061B630EFD}\InprocServer32\1.0.0.0]
    "Class"="testDll.Human"
    "Assembly"="testDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    "RuntimeVersion"="v2.0.50727"
     
    [HKEY_CLASSES_ROOT\CLSID\{71A99D26-0218-4601-B7E6-D3061B630EFD}\ProgId]
    @="testDll.Human"
     
    [HKEY_CLASSES_ROOT\CLSID\{71A99D26-0218-4601-B7E6-D3061B630EFD}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
    J'ai transféré sur un autre poste mon exe delphi, ma dll et mon .reg que j'ai executé, mais hélas à l'execution de l'exe, j'ai le message :"classe non enregistrée", erreur que je reproduis sur mon poste quand je lance la commande "RegAsm.exe /unregister" (là, c'est logique).

    Je précise que j'ai "choisi" comme framework cible le 3.5 qui est la version installée sur "l'autre poste".

    Si quelqu'un peut me dire où je fais ma betise...
    Merci d'avance!

  6. #6
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Pour déployer une dll ActiveX sur un nouveau poste, la manipulation consiste à inscrire la dll dans la base de registre.

    L’utilitaire regasm (http://msdn.microsoft.com/fr-fr/library/tzat5yw6.aspx) permet d’inscrire une librairie dans la base de registre. Cet utilitaire est installé avec Visual Studio (C:\Windows\Microsoft.NET\Framework\v2.0.50727) et son utilisation est la suivante :
    • Pour inscrire l'ActiveX : regasm pathDll.dll /codebase
    • Pour désinscrire l'ActiveX : regasm pathDll.dll /unregister

    Le paramètre /codebase permet de spécifier le chemin d’installation de la dll. Sans ça, il faut que la dll soit installée dans le Global Assembly Cache (GAC).

    Cette commande est à exécuter directement depuis le poste client. Tu retrouveras alors ton ActiveX dans la base de registre

  7. #7
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci pour ton aide.
    J'ai suivi ton conseil (de ta premiere réponse) et j'ai signé l'assembly (meme si j'avoue que je ne comprends pas à quoi ca sert^^). C'est assez desagreable de suivre "betement" vos (bons) conseils, mais comme je suis pressé par le temps...
    Pour info, j'ai reussi à faire fonctionner le tout sur un 3e poste XP. Je suis moi meme sous XP, et donc sur mon poste de dev j'ai généré un fichier reg par la commande regasm /regfile:testdll.reg testdll.dll.
    J'ai copié le tout (.reg, .dll et exe delphi) sur le 3e poste, j'ai double cliqué sur le .reg, j'ai lancé l'exe et magie ca a fonctionné.
    Le problème du 2e poste viendrait donc du fait que ce soit un poste qui est sous Seven ??

  8. #8
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Citation Envoyé par pixigol
    j'ai signé l'assembly (meme si j'avoue que je ne comprends pas à quoi ca sert^^). C'est assez desagreable de suivre "betement" vos (bons) conseils, mais comme je suis pressé par le temps...
    Quelques explications ici :
    http://msdn.microsoft.com/fr-fr/libr...=vs.80%29.aspx

    Citation Envoyé par pixigol
    Le problème du 2e poste viendrait donc du fait que ce soit un poste qui est sous Seven ??
    Disons qu'il faut au minimum s'assurer que le framework que tu utilises est bien installé sur le poste client. Il faut voir aussi si l'OS seven est 64 bits et dans ce cas peut-être compiler ta dll pour la plateforme adéquat.

    Après si ça ne marche toujours pas, il faut regarder ce que fait ta dll, si ça se limite juste à la classe Human, je ne pense pas que tu auras de problème. Si tu fais des chose plus "complexes", il faut voir...

  9. #9
    Nouveau membre du Club
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Points : 25
    Points
    25
    Par défaut
    Merci beaucoup pour ton aide.
    Effectivement je suis en 32 bits, et ca marche niquel sur un vista 32 bits et Seven 32 bits.
    Merci bien!

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

Discussions similaires

  1. [DELPHI 6][OBJET COM] et événement
    Par Desraux dans le forum Langage
    Réponses: 0
    Dernier message: 20/05/2008, 12h22
  2. Réponses: 16
    Dernier message: 06/06/2007, 12h42
  3. Objet COM ou pas en réseau ?
    Par corwin_d_ambre dans le forum Web & réseau
    Réponses: 11
    Dernier message: 13/07/2004, 17h38
  4. [objets COM] "Catastrophic failure"
    Par Air'V dans le forum ASP
    Réponses: 5
    Dernier message: 10/09/2003, 11h45
  5. Désenregistrement d'Objets COM sous Windows
    Par barthelv dans le forum Windows
    Réponses: 2
    Dernier message: 21/05/2003, 15h11

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