Partage
  • Partager sur Facebook
  • Partager sur Twitter

Import Données DLL Delphi en C#

Problème de conversion PAnsiChar en Stringbuilder

    9 octobre 2020 à 14:57:32

    Bonjour à tous,

    Je voudrais importer des données provenant d'une DLL extérieure (codée en Pascal sous Delphi).

    Pour information, cette DLL permet entre autre de lire un code barre.

    La fonction GetBarCode que j'importe est décrite ainsi dans la doc de la DLL:

    bool GetBarCode(char* Value, int* Len)

    function GetBarcode(Value: PAnsiChar; var Len: Integer): Boolean; stdcall; 

    Afin d'utiliser cette fonction dans ma classe C#, je déclare l'import de la fonction:

     [DllImport(DLL, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
     [return: MarshalAs(UnmanagedType.I1)]
     static extern bool GetBarcode([MarshalAs(UnmanagedType.LPStr)] StringBuilder Barcode, ref int length);

    Ensuite j'appelle la fonction à ce moment dans mon code:

                bool Ok = false;
                StringBuilder sbBarCode = new StringBuilder(50);
                string Barcode = string.Empty;
                string s = string.Empty;
                int length = -1;
    
                try
                {
                    Ok = GetBarcode(sbBarCode, ref length);
                    
                   
                    s = sbBarCode.ToString();
                }
                catch
                {
                    return string.Empty;
                }



    Lorsque j'exécute le programme, tout se passe bien jusqu'à ce que je récupère le code barre (sbBarCode).

    En fait je scanne un code barre de 9 caractères, j'ai bien la variable length qui remonte 9 mais la variable sbBarCode me remonte juste 4 caractères, 2 caractère spéciaux, un espace et un caractère vide.

    J'imagine qu'il y a peut-être un problème lors de la récupération de la variable ou un soucis d'encodage mais j'avoue que ça fait un moment que je me casse les dents sur ce problème et que je ne trouve pas de solution.

    J'ai déjà essayer pas  mal de choses comme déclaré sbBarCode en tant que string mais dans ce cas là rien ne remonte, sbBarcode reste vide.

    J'ai également essayé de déclaré CharSet = CharSet.Unicode mais comme on peut s'y attendre c'est pire.

    J'ai aussi essayé de changer le marshalling en mettant un UnmanagedType.BStr au lieu de LPStr mais là encore c'est pire.

    Est ce que quelqu'un aurait une piste pour m'aider à avancer sur ce bug?

    • Partager sur Facebook
    • Partager sur Twitter
      9 octobre 2020 à 16:15:45

      Je pense que le 9ème caractère est le caractère spécial "fin de chaine" \0, donc tout serait bon.
      Tu peux essayer un tableau de caractères (char[]) ce qui se rapprocherait de la définition originelle "Char*"
      • Partager sur Facebook
      • Partager sur Twitter
        9 octobre 2020 à 16:58:52

        Hélas, lorsque j'essaie de récupérer le code barre (sbBarCode) que ce soit en string ou en char[] j'ai à chaque fois une valeur vide.

        C'est pour cela que ce qui me semblait le plus prometteur c'est plutôt un StringBuilder.

        Effectivement, le dernier caractère est le caractère null, c'est pour ça que j'essaie de "marshaliser" la variable avec UnmanagedType.LPStr car ça me paraît être le plus proche de ma source=>

        Pointeur vers un tableau de caractères ANSI terminé par un caractère Null

        malgré cela, au lieu d'avoir un numéro de code barre du type "C123456", je me retrouve avec 3 caractères spéciaux et caractère null...

        A ce stade je ne sais pas si le problème vient d'un mauvais import de la valeur de la variable ou si je dois faire une conversion a posteriori de ma variable sbBarcode...

        • Partager sur Facebook
        • Partager sur Twitter
          9 octobre 2020 à 17:41:39

          Avec le stringbuilder, tu semblais avoir un bon résultat, non ? vu que tu disais récupérer 4 caractères +2 spéciaux + 1 espace+ 1 vide ou alors j'ai mal compris (je crois que c'est ça ^^ ) et c'est 4 caractères que tu récupères et qui sont 2 caractères spéciaux +1 espace + 1 caractère vide, ce qui colle mieux avec la capture du coup ... et du coup, ce n'est pas un caractère vide, mais un caractère de code ascii 28 (en décimal) qui correspond à FileSeparator.

          je remarque aussi que les valeurs dépassent 255. tu as essayé avec un tableau de bytes (byte[]) ?  ou de faire un décodage en ANSI (ou US-ASCII)
          • Partager sur Facebook
          • Partager sur Twitter
            12 octobre 2020 à 8:56:30

            En fait je récupère 4 caractères en tout (au lieu de 9 pour mon codebarre final) 2 spéciaux + 1 espace + 1 Caractère vide.

            Aujourd'hui je vais essayer de voir si j'arrive à décoder ANSI => StringBuilder ce résultat, je vous tiens au courant

            • Partager sur Facebook
            • Partager sur Twitter

            Import Données DLL Delphi en C#

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown