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 :

Utiliser une DLL codée en delphi dans C#


Sujet :

C#

  1. #1
    Membre averti
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Par défaut Utiliser une DLL codée en delphi dans C#
    Bonjour à tous,

    J'ai une dll codée en langage delphi qui contient donc des fonctions en delphi que j'aimerais utiliser dans C# sous Visual Studio 2017.
    Je veux utiliser par exemple la fonction GENERATE contenue dans test.dll.

    Ci-dessous un exemple de code C# que j'ai fait pour utiliser test.dll en delphi en C#.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    namespace AppTest
    {
        Public class Program
        {
            [DllImport("test.dll", CharSet = CharSet.Ansi)]
            public static extern bool GENERATE(string path);
     
            static void Main(string[] args)
            {
                GENERATE(@"C:\Users");
            }
        }
    }
    Mais quand je teste ce programme, j'ai l'erreur suivante :

    System.DllNotFoundException : 'Impossible de charger la DLL 'test.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)'
    Comment résoudre ce problème ?
    J'ai placé test.dll dans le dossier qui contient les fichiers sources C#.

    Comment C# est capable de lire une dll en delphi si Visual Studio ne connaît pas le delphi ?


    Je vous remercie de votre aide.

  2. #2
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Tu as mis le fichier de la dll en action de compilation "Ressource" pour qu'elle soit copiée dans le répertoire de sortie ?

  3. #3
    Membre averti
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Par défaut
    J'ai ajouté la dll depuis Visual Studio en faisant clic droit sur le projet puis ajouter un élément existant, ensuite, dans les propriétés de la dll, j'ai mis "Contenu" en Action de génération et j'ai mis "Toujours copier" (répertoire de sortie). Quand je lance la solution, j'ai toujours le même message d'erreur :
    System.DllNotFoundException : 'Impossible de charger la DLL 'test.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)'

    Comment résoudre cela, s'il vous plaît ?

  4. #4
    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
    bonjour
    Faudrait savoir d'abord si Delhi(Pascal) même sous VS compile ses dll en
    1/ code natif (comme le C ,C++ ou le Fortran ) ou
    2/ MSIL comme vb.net ou CSharp
    Dans le 1 er cas c'est un P/Invoke qu'il faut et même si tu la références ca finira par un message d' "abend" comme le tiens.
    Le P/Invoque nécessite aussi le nom et signature des methods appelées & la traduction des types attendus par ces methods en type compatibles .Net
    Dans le 2 eme cas c'est des "dll" .net et il est légitimé de les référencer.

    Mais les compilateurs Borland privilégiant la rapidité inexécution,je doute fort qu'il compile en .Net

  5. #5
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Delphi c'est pas jeune, à mon avis c'est pour du code natif.

    Citation Envoyé par MABROUKI Voir le message
    un message d' "abend"
    Hein ?

  6. #6
    Membre averti
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Avril 2020
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Avril 2020
    Messages : 28
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    bonjour
    Faudrait savoir d'abord si Delhi(Pascal) même sous VS compile ses dll en
    1/ code natif (comme le C ,C++ ou le Fortran ) ou
    2/ MSIL comme vb.net ou CSharp
    Dans le 1 er cas c'est un P/Invoke qu'il faut et même si tu la références ca finira par un message d' "abend" comme le tiens.
    Le P/Invoque nécessite aussi le nom et signature des methods appelées & la traduction des types attendus par ces methods en type compatibles .Net
    Dans le 2 eme cas c'est des "dll" .net et il est légitimé de les référencer.

    Mais les compilateurs Borland privilégiant la rapidité inexécution,je doute fort qu'il compile en .Net
    C'est du code natif. La dll test.dll ne peut donc s'ajouter directement en références dans la solution C#.

    Je vais détailler mon problème.
    J'ai une dll créée avec du langage delphi (BorlandDelphi 7) qui contient donc des fonctions en delphi que je voudrais utiliser dans C# sous Visual Studio 2017.
    Je veux utiliser par exemple la fonction GENERATE_FILE contenue dans test.dll.

    Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure GENERATE _FILE(Path, Input_File : AnsiString); stdcall; 
     
     
    procedure GENERATE _FILE(Path, Input_File : AnsiString); stdcall;
    var
    ...
     
    begin
    …
    GENERATE_CALC(Path_And_File, CRC32, Total, err);
    …
    end;

    Dans C#, je veux utiliser la fonction GENERATE_FILE contenu dans test.dll mais quel est le type pour les paramètres Path et Input_File dans C# par rapport aux types de delphi (ci-dessus) ?

    Ci-dessous un exemple de code C# que j'ai fait pour utiliser test.dll dans C#.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    namespace AppTest
    {
        Public class Program
        {
            [DllImport("test.dll", CharSet = CharSet.Ansi)]
            public static extern bool CREATE_FILE(string pathDirectory, string filename);
     
            static void Main(string[] args)
            {
                GENERATE_FILE(@"C:\Users", "file.txt");
            }
        }
    }

    J'ai ajouté test.dll depuis Visual Studio en faisant clic droit sur le projet puis ajouter un élément existant, ensuite, dans les propriétés de la dll, j'ai mis "Contenu" en Action de génération et j'ai mis "Toujours copier" (répertoire de sortie). Quand je lance la solution, j'ai test.dll dans bin\Debug.

    Mais quand je teste ce programme, j'obtiens l'erreur suivante à la ligne GENERATE_FILE(@"C:\Users", "file.txt"); :

    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '
    Comment résoudre cela ?
    Je pense que le problème est dû au type des paramètres dans la fonction GENERATE_FILE. Quel sont les types équivalents entre delphi et C# pour la fonction GENERATE_FILE ?

    Merci.

  7. #7
    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
    bonjour

    Tu peux essayer ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
     [DllImport("test.dll",  CharSet = CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]
            public static extern bool CREATE_FILE(string pathDirectory, string filename);
    Mais attention les appels entre langages différents sont truffés de pièges car les types sont définis différemment,particulièrement les chaines et leur buffers .

    J'utilise peu Delphi et le mieux pour s'exercer est d’écrire soi-même ses dll Delphi avec les différents types de Delphi et de faire les appels de plateforme.
    bon code...

  8. #8
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par speedcristal Voir le message
    System.DllNotFoundException: 'Unable to load DLL' test.dll ': The specified module could not be found. (Exception from HRESULT: 0x8007007E) '
    Le message d'erreur semble plutôt indiquer qu'il ne trouve pas la DLL. Ce ne serait pas un problème de path ou d'antivirus ?

    Sinon tu peux essayer ce programme, il permet de connaitre exactement les fonctions qui sont dans la DLL.

  9. #9
    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
    Bonjour

    Le hic dans ta dll je presume "maison" c'est que le type AnsiString dans Delphi 7 est un type de base c.à.d un type valeur .
    Comme c'est un type de base pour les caractères ANSI dit aussi ASCII,il faut convertir tes paramètres de strings en tableaux de bytes ASCII avant de les passer.
    Aussi si tu es l'auteur ou tu as le code source pascal ,tu dois changer la signature de ton method GENERATE_FILE :

    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure GENERATE_FILE(Path, Input_File : AnsiString); stdcall;
    var
    fileName :string  ;
     
    begin
       fileName := PChar(Path + Input_File);
    end ;

    voici un lib pascal avec les declarations d' "exports" des "dll" .
    Il montre aussi qu'en Delphi comment le type PChar est un vrai "razoir 'Occam" :

    code behind pascal:
    Code pascal : 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
    library ProjMyLib;
     
    { 
     
    uses
      SysUtils,
      Classes;
     
    {$R *.res}
    function AddIntegers(const _a, _b: integer): integer; stdcall;
    begin
      Result := _a + _b;
    end;
    function CountChars(_s: Pchar): integer; StdCall;
    begin
      Result := Length(_s);
    end;
    function ConcatChaineAnsi(_s1  , _s2: AnsiString): Pchar; StdCall;
    begin
      Result := strCat( Pchar(_s1) ,Pchar(_s2));
    end;
     
    procedure GENERATE_FILE(Path, Input_File : AnsiString); stdcall;
    var
    fileName : Pchar;
     
    begin
       fileName :=strCat( Pchar(Path) ,Pchar(Input_File));
    end ;
     
       exports
          AddIntegers, CountChars,ConcatChaineAnsi ,GENERATE_FILE;
    begin
    end.
    code behind .cs appelant :
    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
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices ;
    namespace WinTestDelphi
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                int a = 100;
                int b = 301;
                this.label1.Text = AddIntegers(a, b).ToString();
                string s = "Dylan";
                this.label2.Text = CountChars(s).ToString();
     
                string s0 = "Marlene";
                string s1 = "jobert";
                byte[] s0bytes = Encoding.ASCII.GetBytes(s0);
                byte[] s1bytes = Encoding.ASCII.GetBytes(s1);
                this.label3.Text = ConcatChaineAnsi(s0bytes, s1bytes);
            }
     
     
            [DllImport("ProjMyLib.dll",CharSet=CharSet.Ansi,CallingConvention=CallingConvention.StdCall)]
            public static extern int AddIntegers(int a, int b);
            [DllImport("ProjMyLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int CountChars(string name);
            [DllImport("ProjMyLib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern string ConcatChaineAnsi(byte[] s0, byte[] s1);
        }
    }
    n'oublie d'ajouter le fichier dll et de le compiler en contenu.

    bon code.

Discussions similaires

  1. utiliser une variable déclaré en delphi dans un sql
    Par jamdinhe dans le forum Bases de données
    Réponses: 12
    Dernier message: 28/06/2018, 09h32
  2. Utiliser une DLL écrite en C++ dans delphi
    Par totof41 dans le forum Langage
    Réponses: 3
    Dernier message: 07/05/2014, 08h39
  3. Utiliser une DLL Matlab sous Delphi
    Par airefrais dans le forum Langage
    Réponses: 4
    Dernier message: 24/07/2009, 10h16
  4. Utiliser une dll C# avec delphi
    Par Gruick dans le forum Débuter
    Réponses: 8
    Dernier message: 19/06/2008, 10h23
  5. Utiliser une DLL sans le .LIB dans Visual Studio 2005
    Par lekernel dans le forum Visual C++
    Réponses: 5
    Dernier message: 02/08/2007, 08h54

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