DLL en C++ standard utilisé par une IHM en C#/WPF [Résolu]

BunoCS 14175 Messages postés lundi 11 juillet 2005Date d'inscription 16 octobre 2018 Dernière intervention - 22 juin 2009 à 21:56 - Dernière réponse : BunoCS 14175 Messages postés lundi 11 juillet 2005Date d'inscription 16 octobre 2018 Dernière intervention
- 6 juil. 2009 à 15:05
Amis de la communautés bonjour!

J'aimerais savoir comment, depuis une IHM faite en C#/WPF, appeler une classe C++ se trouvant dans une DLL?

Sur le web, je vois principalement 2 méthodes:

- P/Invoke et DllImport : dans tous les exemples que je trouve ce sont
des fonctions C qui sont appelées. Comment faire dans le cas de
plusieurs classes? Je ne vais pas faire l'énumération de l'API
complète, non?

- faire une classe Wrapper en C++ managé appelant ma classe en C++ non
managé. A priori, ceci ne fonctionne que si la DLL a été faite avec des
objets COM. Vrai? Sinon, comment faire exactement?


Je précise que la DLL ne contient que du C++ tout à fait standard.
D'avance, merci de vos retours (j'ai également posé la question sur CppFrance)

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
Lutinore 3248 Messages postés lundi 25 avril 2005Date d'inscription 27 octobre 2012 Dernière intervention - 22 juin 2009 à 23:46
3
Merci
Salut, c'est possible via P/Invoke, on utilise l'attribut DllImport et la convention d'appel ThisCall . La principale difficulté c'est qu'il te faut au moins une fonction en C pour créer l'objet avec "new" et une autre pour détruire l'objet avec "delete". J'ai posté un exemple ici -> http://www.csharpfr.com/forum/sujet-UTILISATION-FONCTIONS-CLASSE-PARTIR-DLL-CPLUSPLUS-DANS-APPLICATION_1272276.aspx

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 - 24 juin 2009 à 04:45
3
Merci
- Effectivement il faut avoir accès au code source ou une petite dll supplémentaire en flat C juste pour instancier et détruire la classe ou se tourner vers le C++/CLI pour mixer du code natif et du code managé.

- Oui tu vas devoir écrire toutes les définitions P/Invoke des méthodes ( que tu souhaites utiliser ) de ta classe native.

- EXTERN_C permet d'eviter la décoration des noms de fonctions mais pour les méthodes contenues dans une classe j'ai jamais trouvé comment l'eviter. J'utilise DumpBin.exe qui se trouve soit dans le platforme SDK ( soit dans VS, je sais plus ) pour trouver le nom décoré.

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 - 22 juin 2009 à 23:53
0
Merci
Voilà l'exemple mis au propre :

// C++



#define EXTERN_C extern "C"
#define DLLEXPORT __declspec(dllexport)



class DLLEXPORT Device
{



private:



 HWND m_hWnd;



public:



 Device( HWND hWnd );
 ~Device( );



 BOOL Clear( UINT color );



};

EXTERN_C DLLEXPORT Device* CreateDevice( HWND hWnd )
{
 Device* pDevice = new Device( hWnd );
 return pDevice;
}



EXTERN_C DLLEXPORT void DestroyDevice( Device* pDevice )
{
 if ( pDevice != NULL )
 {
  delete pDevice;
  //pDevice = NULL;
 }
}



// C#



[ SuppressUnmanagedCodeSecurity ]
internal sealed class Device
{
    private const string DLL_NAME = @"GX.dll";



    [ DllImport( DLL_NAME, CallingConvention = CallingConvention.StdCall ) ]
    public static extern IntPtr CreateDevice( IntPtr hWnd );
    [ DllImport( DLL_NAME, CallingConvention = CallingConvention.StdCall ) ]
    public static extern void DestroyDevice( IntPtr pDevice );



    [ DllImport( DLL_NAME,
        CallingConvention = CallingConvention.ThisCall,
            EntryPoint = "
[mailto:?Clear@Device@@QAEHI@Z
?Clear@Device@@QAEHI@Z
]
" ) ]
    [ return: MarshalAs( UnmanagedType.Bool ) ]
    public static extern bool Clear( IntPtr pDevice, int color );
}
Commenter la réponse de Lutinore
BunoCS 14175 Messages postés lundi 11 juillet 2005Date d'inscription 16 octobre 2018 Dernière intervention - 23 juin 2009 à 20:56
0
Merci
Ok merci, je vais regarder ça de plus près.
Quelques questions en attendant:
- pour ajouter les fonctions create() et destroy(), cela suppose que j'ai accès au code de la DLL, ce qui est effectivement le cas pour moi. Dans le cas contraire, la méthode P/Invoke ne peut donc pas s'appliquer?
- la fonction Clear() fait partie de la classe Device. Je dois donc lister toutes les fonctions de toutes mes classes dans le DllImport?
- comment fait-on pour connaître la décoration des fonctions?

NB: y'a des mots clés que je ne maitrise pas encore (sealed, MarshalAs). Je file me documenter..mais je reviendrais sûrement

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Commenter la réponse de BunoCS
BunoCS 14175 Messages postés lundi 11 juillet 2005Date d'inscription 16 octobre 2018 Dernière intervention - 6 juil. 2009 à 15:05
0
Merci
Merci Lutinore, ça m'a bien aidé, même si le projet a fait qu'on utilise la solution du Wrapper...

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Commenter la réponse de BunoCS

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.