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#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    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
    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
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    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
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    Par défaut
    Merci beaucoup pour vos réponses, je teste ça ce matin!

  5. #5
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 36
    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
    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

+ 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