Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010
-
3 mai 2010 à 15:08
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010
-
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
A voir également:
Tentative de chargement d'un programme de format incorrect
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 6 mai 2010 à 12:57
*.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#.
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 8 mai 2010 à 13:40
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.
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 7 mai 2010 à 15:01
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.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 4 mai 2010 à 12:48
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..
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 4 mai 2010 à 16:39
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*.
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 5 mai 2010 à 00:47
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.
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 5 mai 2010 à 09:15
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();
}
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.
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 7 mai 2010 à 09:39
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 );
}
}
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 7 mai 2010 à 09:46
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 ?
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 7 mai 2010 à 16:31
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.
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 10 mai 2010 à 09:45
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)
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 10 mai 2010 à 10:07
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.
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 10 mai 2010 à 11:26
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.
Belisir
Messages postés18Date d'inscriptionlundi 26 avril 2010StatutMembreDernière intervention20 mai 2010 10 mai 2010 à 14:10
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.