Invoquer une DLL c++ dans programme c# [Résolu]

Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 3 mai 2010 à 15:08 - Dernière réponse : Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention
- 20 mai 2010 à 10:42
Bonjour,

depuis quelques jours je me heurte à résoudre un problème qui à première vue, ne semblait pas poser de problème : Invoquer les méthodes d'une DLL faite en C++, dans un programme C# qui fait office d'IHM.


En effet après avoir généré mon .lib & .dll, j'ai souhaité de la même façon les importer.

Voici les premiers s'griboullit que j'ai pu faire, en m'inspirant des divers réponses apportés à d'autres personnes, ayant des problèmes du genre.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices; //pour l'import d'une DLL






namespace monInterface
{
[DllImport("maDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    static extern void comRapide(std::string & NumAppelant, std::string & NumAppele) const;  



    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void bt_Quitter(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
}


Ce que je ne comprend pas :

- Les différentes options à mettre, comme CharSet, ou CallingConvention.
- Pourquoi le "void" est compté comme : class, delegate, enum, interface ou struct attendu
- Si je met Interface à la place de void, du coup ma fonction importée n'est plus reconnue


Finalement, auriez vous un "how to", clair et précis pour comprend comme ça marche, car il s'agit bien de comprendre et non de recopier vos réponses ;) Quoi que, recopier vos solutions est faisable dans un premier temps :p
Afficher la suite 

Votre réponse

24 réponses

Meilleure réponse
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 5 mai 2010 à 00:40
3
Merci
Ah si tu possèdes le code ça change tout.. oui bonne idée en char* ou en wchar_t* si tu veux de l'unicode.

Pour l'interop tout est expliqué ici :

[url]http://msdn.microsoft.com/fr-fr/library/sd10k43k(v=VS.100).aspx/url

Merci Lutinore 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de Lutinore
Meilleure réponse
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 6 mai 2010 à 12:57
3
Merci
*.tlb c'est pour les librairies COM.

Les ressources c'est une mauvaise piste.

Le Chapitre qui t'intéresse c'est "Consommation de fonctions DLL non managées" ça va t'expliquer l'attribut DLLImport.

Impossible d'importer une librairie C/C++ dans ton projet C#, il faut simplement la mettre dans le dossier de l'application et écrire les bonne définitions Dllimport dans ton code C#.

Merci Lutinore 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de Lutinore
Meilleure réponse
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 8 mai 2010 à 13:40
3
Merci
On utilise pas les *.lib, et les .h en C#, je t'ai dit DLLImport ça marche avec un simple copier/coller dans le répertoire de l'appli. toutes les dépendances doivent y être sauf celles qui doivent être dans le répertoir System de Windows.

Merci Lutinore 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de Lutinore
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 7 mai 2010 à 15:01
1
Merci
Non rien d'autre, un simple copier/coller dans le répertoire suffit mais il se peut que ce soit une dépendance de la ta dll native qui soit introuvable.
Commenter la réponse de Lutinore
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 4 mai 2010 à 12:48
0
Merci
Salut, pour comprendre DllImport il faut connaitre un mimimum le C++. La définition de fonction que tu as donné c'est du C++ ça ne marchera pas en C#. En plus de ça pas de chance pour toi ça utilise les "std::string" qui sont des classes de la STL et qu'on ne peut pas utiliser en c#, il y'a bien un "trick", il faudrait chercher l'offset de début de chaine etc..
Commenter la réponse de Lutinore
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 4 mai 2010 à 16:39
0
Merci
Bonjour,

sauf que ! je peux tout à fait changer les "std::string" en char * et hop roule. Certes je ne suis pas un fou du C++, mais je me débrouille et bien pire que ça je cherche à apprendre ;)

Du coup pour pouvoir importer ma DLL c++ en C# je suis entrain de convertir mes string en char*.


Bonne idée ?
Commenter la réponse de Belisir
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 5 mai 2010 à 00:47
0
Merci
J'avais zappé que tu avais généré la DLL toi même, dans ce cas tu peux même tenter un wrapper en C++/CLI c'est à dire faire une librairie .NET accessible en C# mais qui contient aussi du code natif.
Commenter la réponse de Lutinore
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 5 mai 2010 à 09:15
0
Merci
Bonjour,


si je fais sur .NET du coup je vais être contraints par les versions de framework. Au niveau de la DLL ça me pose problème car je souhaite qu'elle soit accessible sans ce type de contraintes. Pour la petite interface c'est juste pour "tester" du coup je peux m'embêter avec ça.

Sinon pour l'interop j'avais déjà essayé d'ajouter une référence comme indiquer mais visiblement mon .dll ni lui plaisait pas, une message du type :

'Une référence maLib n'a pas pu être ajoutée. Assurez-vous que ce fichier est accessible et qu'il s'agit d'un assembly ou d'un composant COM valide.'

D'ou ma tentative avec :


      public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }

            public class MaLib
            {

                [DllImport("maLIB.dll", CharSet = CharSet.Auto)]
               public static extern int maMETHODE();
            }
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 5 mai 2010 à 12:02
0
Merci
Re-bonjour,

je suis désolé mais j'ai bien parcourus http://msdn.microsoft.com/fr-fr/library/sd10k43k(v=VS.100).aspx, sans pour autant trouver chaussure à mon pied.

En effet j'aurais bien utilisé la méthode d'import d'une référence, mais je ne trouve pas de .tlb, je n'ai qu'un .lib et un .exp suite à la compilation de ma DLL.

De plus j'ai aussi regardé du côté de comment incorporer des bibliothèques de types comme des ressources Win32 dans les applications .NET, mais j'ai peur de faire fausse route.

La question étant : qu'es ce que je n'ai pas saisis dans le processus de compilation d'une DLL c++, puis importation vers du C#.

A noter que j'ai bien changer tout mes paramètres/attributs de mes méthode/prototypes en char *, afin de rectifier le tir précédent.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 6 mai 2010 à 10:42
0
Merci
Bonjour,

je n'ai toujours pas réussis à avancer avec ma DLL.

Si cette histoire d'import du .tlb est la solution, comment ça se fait que je n'arrive pas à le générer à la compilation de la DLL sous VC++.

Avez vous des idées ?
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 7 mai 2010 à 09:39
0
Merci
Bonjour,

voici mon avancement : je suis donc passé par tes conseils, et j'en arrive à ce stade, qui me "semble" proche de la solution. Seulement problème il me dit
Impossible de charger la DLL 'maDll.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)










  

    namespace monInterface
    {



        public class maDll
        {
            [DllImport("meDll.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr maMethode([MarshalAs(UnmanagedType.LPWStr)] StringBuilder param1, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder param2);


        }
     

          private void bt_monBouton(object sender, RoutedEventArgs e)
            {
                StringBuilder param1 = new StringBuilder ();
                StringBuilder param2 = new StringBuilder ();

                APITelephone.maMethode(param1 , param2 );


            }
}
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 7 mai 2010 à 09:46
0
Merci
Pas de fonction d'édition :(

Je corrige donc et j'apporte quelques compléments :

Il y a une faute de frappe dans le sujet précédent, c'est bien : [DllImport("maDll.dll", CharSet...]

De plus j'ai pourtant bien mis ma DLL dans le répertoire débug et release de mon projet C#, il devrait les trouver ? Dois je spécifier quelques choses dans les propriétés ?
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 7 mai 2010 à 16:31
0
Merci
Bonjour,

la Dll native a en effet plusieurs dépendances Dont des libMysql.dll

Du coup je dois mettre aussi ces librairies & includes dans le projet C# ; problème, il y a pas à ma connaissance d'include à faire dans les propriétés du projet.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 09:45
0
Merci
Bonjour,


le problème avance, mais je suis confronté à un nouveau problème lorsqu'il va pour appeler une méthode contenue dans la DLL. Voici le message sachant que le prototype est :

public class maClasse
        {
            [DllImport("C:\\Users\\toto\\Documents\\Visual Studio 2008\\Projects\\monProg\\monProg\\maDll.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr DialRapide([MarshalAs(UnmanagedType.LPWStr)] StringBuilder NumAppelant, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder NumAppele);


        }


            private void bt_montest(object sender, RoutedEventArgs e)
            {



                StringBuilder NumAppelant = new StringBuilder ();
                StringBuilder NumAppele = new StringBuilder ();

                APITelephone.DialRapide(NumAppelant, NumAppele);

            }




Erreur :
Tentative de chargement d'un programme de format incorrect. (Exception de HRESULT : 0x8007000B)
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 10:07
0
Merci
Re bonjour,

le problème viendrait du fait que le .Net 64bit refuse d'être lié à une dll 32bit. Vous confirmeriez ? Du coup je cherche à compiler la DLL comme il se doit, je viendrait vous informer si c'est bien ça ou non.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 11:26
0
Merci
Re re bonjour,

je confirme que le problème de mauvais format vient bien de cette histoire de 32/64 bits. Seulement, je ne trouve pas à forcer l'exécution de mon IHM C# en 32 bits.

Une idée ?
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 14:10
0
Merci
J'ai donc essayé de forcé la compilation de mon IHM C# en X86 et "any CPU", mais l'un comme l'autre me retourne des erreurs.


Pour X86 :
Impossible de charger la DLL 'C:\Users\moi\Documents\Visual Studio 2008\Projects\monInterface\monInterface\maDLL.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E)


Or tout est bon endroit puisqu'en normal il l'a trouve ;)

Pour Any CPU :
Tentative de chargement d'un programme de format incorrect. (Exception de HRESULT : 0x8007000B)



Le format ne lui convient toujours pas.

Sachant que ma DLL C++ a été fait avec win32, je ne vois pas trop comment avancer.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 15:15
0
Merci
Bonjour,


j'en reviens au même problème quelque soit la plateforme utilisée, je me retrouve avec un mauvais format.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 10 mai 2010 à 17:26
0
Merci
De nouveau bonjour,

j'ai tenté pas mal de chose dont voici la liste :

- Modification de la propriété de l'adressage de base fixe en /fixed:no

- Changement du type de plateforme cible (en mettant X64)

- Forçage de la plateforme de l'IHM C# en x86


Rien n'y fait le format n'est toujours pas le bon selon lui.
Commenter la réponse de Belisir
Belisir 18 Messages postés lundi 26 avril 2010Date d'inscription 20 mai 2010 Dernière intervention - 11 mai 2010 à 10:16
0
Merci
Bonjour,

auriez vous une quelconque aide à me proposer, je ne dois pas être loin du but ?
Commenter la réponse de Belisir

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.