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

Delphi Discussion :

Utiliser une DLL C# a partir de delphi


Sujet :

Delphi

  1. #1
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 2
    Points
    2
    Par défaut Utiliser une DLL C# a partir de delphi
    Comment utiliser une DLL ecrite en C# a partir de delphi5 ?

    J'ai une dll que l'on va appeler FaitLeCafe.dll qui m'a été fournie avec un exemple d'appel en C# :
    ...
    using FaitLeCafe;
    ...
    FaitLeCafe.FaitLeCafe mydll = new FaitLeCafe.FaitLeCafe();
    mydll.FaitLeCafeEtApporte("A machin");
    string resulta = mydll.ReadData.ToString();

    Si je decode correctement :
    Y a un namspace FaitLeCafe qui contiens un objet FaitLeCafe
    ils declarent donc mydll comme etant un objet de type FaitLeCafe
    puis invoquent son constructeur.

    Par la suite est apellé la fonction FaitLeCafeEtApporte
    L'objet mydll a une propriété contenant le résultat de FaitLeCafeEtApporte

    J'aimerais pouvoir l'appeler a partir de mon petit delphi5 (il est vieux je sais ^^)
    pourriez vous m'aider ;-p

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Appelez du code DotNet à partir de code Win32? C'est possible cela.
    L'intéropérabilité des langages existe sur la plateforme DotNet, mais pour cela tu dois utiliser un Delphi qui supporte DotNet.

    L'inverse par contre est vrai, via le mécanisme de Reflection, P/Invoke ou VLI.
    Personellement je n'ai jamais réussi à faire fonctionner le P/Invoke sous BDS2005 .

    Sinon à partir de Delphi5 comme cela, c'est impossible.

  3. #3
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    Si il est possible d'appeler des dll .NET par des programmer Win32.
    Voilà une petit exemple ... la DLL (lib) est écrite en D2006 (.NET) et compilé dans un assembly (.DLL)
    Mais je pense qu'il faut que la DLL soit prévue pour... (voir le code suivant avec la directive {$UNSAFECODE ON} et l'inclusion de l'unité System.Runtime.InteropServices (à vérifier ... je pense que le livre de Olivier DAHAN traite de cela ... cela fait un bout de temps que je ne fait plus de Delphi... désolé)

    Le prog qui l'apelle est un prog D7 tout ce qu'il y a de normal.

    L'Assembly DLL de D2006.NET
    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
     
    library Library1;
     
    {$UNSAFECODE ON}
    uses
      SysUtils,
      Classes,
      System.Reflection,
      System.Runtime.InteropServices;
     
    [assembly: AssemblyTitle('DLL D2006')]
    [assembly: AssemblyDescription('DLL Demo D2006')]
    [assembly: AssemblyConfiguration('')]
    [assembly: AssemblyCompany('OctalWorks')]
    [assembly: AssemblyProduct('OW - DLL2006')]
    [assembly: AssemblyCopyright('OctalWorks(C) 2006-2007')]
    [assembly: AssemblyTrademark('OctalWorks (C) 2006-2007')]
    [assembly: AssemblyCulture('')]
     
    //
    // Version information for an assembly consists of the following four values:
    //
    //      Major Version
    //      Minor Version 
    //      Build Number
    //      Revision
    //
    // You can specify all the values or you can default the Revision and Build Numbers 
    // by using the '*' as shown below:
     
    [assembly: AssemblyVersion('1.0.*')]
     
    //
    // In order to sign your assembly you must specify a key to use. Refer to the 
    // Microsoft .NET Framework documentation for more information on assembly signing.
    //
    // Use the attributes below to control which key is used for signing. 
    //
    // Notes: 
    //   (*) If no key is specified, the assembly is not signed.
    //   (*) KeyName refers to a key that has been installed in the Crypto Service
    //       Provider (CSP) on your machine. KeyFile refers to a file which contains
    //       a key.
    //   (*) If the KeyFile and the KeyName values are both specified, the 
    //       following processing occurs:
    //       (1) If the KeyName can be found in the CSP, that key is used.
    //       (2) If the KeyName does not exist and the KeyFile does exist, the key 
    //           in the KeyFile is installed into the CSP and used.
    //   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
    //       When specifying the KeyFile, the location of the KeyFile should be
    //       relative to the project output directory. For example, if your KeyFile is
    //       located in the project directory, you would specify the AssemblyKeyFile 
    //       attribute as [assembly: AssemblyKeyFile('mykey.snk')], provided your output
    //       directory is the project directory (the default).
    //   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
    //       documentation for more information on this.
    //
    [assembly: AssemblyDelaySign(false)]
    [assembly: AssemblyKeyFile('')]
    [assembly: AssemblyKeyName('')]
     
    //
    // Use the attributes below to control the COM visibility of your assembly. By
    // default the entire assembly is visible to COM. Setting ComVisible to false
    // is the recommended default for your assembly. To then expose a class and interface
    // to COM set ComVisible to true on each one. It is also recommended to add a
    // Guid attribute.
    //
     
    [assembly: ComVisible(False)]
    //[assembly: Guid('')]
    //[assembly: TypeLibVersion(1, 0)]
     
    function Multiplier(a, b : integer): integer;
    begin
      result := a*b;
    end;
      exports Multiplier;
     
    begin
     
    end.
    Le programme D7 Win32
    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
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    function Multiplier(a: Integer; b: Integer): Integer; stdcall;external 'Library1.dll';
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var i : integer;
    begin
      i := Multiplier(13,2);
      ShowMessage(IntToStr(i));
    end;
     
    end.
    Cordialement

  4. #4
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Donc la solution serait de l'inverse P/Invoke.

    Sinon Octal ton exemple de DLL dotnet contenant une seule fonction, c'est typique de l'api win32 avec des proc rangées dans les dll. Il aurait fallu prendre un cas d'une DLL contenant des classes, des composantes de langage propre à .net.

  6. #6
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Je dois avouer que je suis trop inculte pour tout comprendre dans vos réponses...

    La méthode décrite par Octal ca je connaissais et d'ailleurs j'esperais obtenir une DLL de cette forme ^^

    Apres avoir lu les articles proposés j'ai compris que je ne comprenais rien...

    De plus dans cette DLL rien n'est fait pour que l'on puisse l'appeler avec du code Win32 dans le sens ou il ne semble y avoir que un namespace et un objet...


  7. #7
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    Citation Envoyé par Fabrice ROUXEL 1
    Donc la solution serait de l'inverse P/Invoke.

    Sinon Octal ton exemple de DLL dotnet contenant une seule fonction, c'est typique de l'api win32 avec des proc rangées dans les dll. Il aurait fallu prendre un cas d'une DLL contenant des classes, des composantes de langage propre à .net.
    Pour récupérer des classes .NET je ne pense pas que l'on puisse le faire car les mécanisme d'instantiations ne sont plus les meme. Cela dit il est tjr possible d'utiliser une assembly qui expose des fonctions simples telle que celle de la DLL que j'ai posté pour cacher les appels à des objets .NET, c'est d'ailleur tout l'interet. Pour le reste, sachez tout de meem que les Unit Delphi en .NET ne sont rien de plus que de Super-Classes .NET où les fonctions globales sont de simple méthodes de classes.

  8. #8
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Après avoir fait des pieds et des mains j'ai réussit a obtenir une DLL dite comme etant compatible win32...

    Ceci dit l'explication que j'en ai eu est la suivante :
    La classe contenue dans la DLL et appelée FaitLeCafe.

    J'ai donc regardé les points d'entrée et j'ai :
    DllCanUnloadNow
    DllGetClassObject
    DllRegisterServer
    DllUnregisterServer

    D'autre part j'ai pris cette Dll pour la mettre dans un petit projet C# pour voir ce que j'y trouvais d'interessant :

    Namspace._FaitLeCafe => Type interface
    Namspace.FaitLeCafe => Type interface
    Namspace.FaitLeCafeClass => Type classe

    Aurais-je loupé un train ?
    Pourriez vous eclairer ma lanterne qui n'a plus de pétrole ni d'electricité ?

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    D'autre part j'ai pris cette Dll pour la mettre dans un petit projet C# pour voir ce que j'y trouvais d'interessant :

    Namspace._FaitLeCafe => Type interface
    Namspace.FaitLeCafe => Type interface
    Namspace.FaitLeCafeClass => Type classe

    Aurais-je loupé un train ?
    Pourriez vous eclairer ma lanterne qui n'a plus de pétrole ni d'electricité ?

    Une interface tu peux la voir comme une classe abstraite.
    Elle posséde des méthodes ou des propriétés mais pas de variables membres.
    Elle n'implémente aucune méthode.L'implémentation est réservée à une classe d'implémentation.
    Dans l'interface il n'y a pas d'indicateur override, reintroduce ou virtual.
    UNe interface ne s'instancie pas.

    exemple

    déclare une interface:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IFaitLeCafe = interface
       [ici le guid]
        procedure Preparer;
      end;
    declare une classe qui implemente l'interface:

    TinterfacedObject implemente _AddRef, _Release et QueryInterface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TFaitLeCafeClass = class(TInterfacedObject, IFaitLeCafe)
      procedure Preparer;
      end;
    implementation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TFaitLeCafeClass.Preparer
    begin
      // le code qui fait le cafe.
    end;
    Cree un objet et une interface qui pointe dessus + appel de la methode.
    procedure TForm.BoutonClick(Sender: TObject);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
       _FaitLeCafe: IFaitLeCafe;
       FaitLeCafe: TFaitLeCafeClass;
     
    begin
       _FaitLeCafe := TFaitLeCafeClass.Create; 
       _FaitLeCafe.Prepare;
    end;
    L'avantage de l'utilisation des interfaces réside dans la gestion automatique des objets via _addref _release.

    tu peux aussi faire des trucs comme

    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
    I1 = Interface
       procedure truc;
     end; 
     
     TC1 = class(TInetrfacedObject, I1)
     private
      FC2: TC2;
     public 
     property C2: TC2 read FC2 write FC2 implements I1;
     
     TC2 = class
      procedure truc;
     end;
     
      procedure TC2.Truc; 
      begin
      end;
     end;
    IL y a bien d'autres consiération à apporterau sujet des interfaces qui sont à la base du modéle COM, mais pour une premiere approche et l'utilisation de ta DLL c'est me semble t'il suffisant.

    ps: Les interfaces permettent des conceptions agiles et tres modulables.
    elles sont au coeur des design patterns.

  10. #10
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Je ne comprends pas tout bien

    IFaitLeCafe = interface
    [ici le guid]
    procedure Preparer;
    end;
    => je ne connais pas le GUID (comment peut on l'obtenir ?)

    D'autre part je ne vois pas comment on fait le lien a cette fameuse DLL.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Ctrl + Shift + G

  12. #12
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Bon ben merci a ceux qui ont tenté de m'apporter de l'aide.
    J'abandonne ici (je ne suis pas capable de comprendre et de mettre en oeuvre vos réponses)

Discussions similaires

  1. Utiliser une DLL écrite en C++ dans delphi
    Par totof41 dans le forum Langage
    Réponses: 3
    Dernier message: 07/05/2014, 08h39
  2. Utiliser une DLL Delphi avec C#
    Par h8ciz dans le forum Windows Forms
    Réponses: 3
    Dernier message: 27/09/2007, 16h46
  3. utiliser une DLL C++ dans un Exe Delphi
    Par rudi0 dans le forum Delphi
    Réponses: 1
    Dernier message: 13/12/2006, 22h49
  4. Réponses: 1
    Dernier message: 18/07/2006, 16h44
  5. [DLL] utiliser une DLL a partir d' une DLL et un .def
    Par venomelektro dans le forum MFC
    Réponses: 9
    Dernier message: 07/12/2004, 14h01

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