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 :

Interfaçage avec du C++


Sujet :

C#

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut Interfaçage avec du C++
    Bonjour,

    Je souhaiterai utiliser une classe écrite en C++ sous forme de librairie dans mon code C#.
    Je fais cela pour gagner en rapidité par rapport au code C#.
    Mais j'ai lu que la seule possibilité était d'écrire une dll en C++ pour l'utiliser en C#.
    Toutefois, je crois savoir que la dll n'est utilisée qu'au moment de l'exécution du programme, donc je craint perdre du temps d'exécution lors de l'ouverture de la dll.
    Existe t-il une façon d'utiliser du code C++ dans du C# sans perdre du temps en ouverture de librairie (mode static)?
    Peut-on compiler le code C++ dès le départ sans perdre du temps lors de l'ouverture de la librairie en l'intégrant dès le départ dans du C# (wrapper?)?

    Bref, je ne sais pas comment procéder pour ne pas perdre en vitesse d'exécution ce qui peut pas être perdu lors de l'ouverture de la librairie?

    Merci pour vos réflexions.

  2. #2
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Le temps de chargement de la bibliothèque devrait être négligeable comparé au temps d'utilisation de celle-ci.

    Le vrai problème potentiel est au niveau des appels aux procédures de la bibliothèque mêmes.
    Si les procédures (méthodes C++) font des traitements très légers (return a + b ) alors l'overhead de l'interop peut se faire ressentir.
    Sinon si elles font des opérations raisonnablement complexes et donc longues alors aucun souci.

    Pour l'interfaçage tu as plusieurs solutions :
    - C++/CLI si tu as peu de classes C++ à utiliser,
    - SWIG si tu as un existant C++ plus conséquent,
    - COM mais seulement si tu veux exposer ton composant C++ à autre chose que .Net (VBA par exemple) car cela nécessite de l'adapter.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Merci, c'est clair, je peux donc utiliser une dll sans trop de soucis pour le temps d'exécution.

    Mais pour interfacer une seule classe C++, suite obligé d'utiliser du CLI ou non?

  4. #4
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui même pour une classe s'interfacer avec du C++ n'est jamais complètement trivial, contrairement à l'interfaçage avec C qui est géré nativement via P/Invoke.

    Donc si tu n'as qu'une classe un simple wrapper C++/CLI fera l'affaire.
    Pour faire ton wrapper tu as de nombreuses ressources disponibles dont : http://www.codeproject.com/Articles/...s-than-minutes

    Mais attention si l'API de cette classe consomme ou renvoie des types complexes C++ il faudra bien sûr aussi les mapper.
    Dans ce cas SWIG est un outil qui fait parfaitement l'affaire.

    C'est dans l'autre sens (appel de .Net depuis C++ natif) que ça devient plus tricky.
    Et là bien sûr niveau ressources c'est la dèche ... mais il y en a au moins une par ton serviteur : Using C# from native C++ with the help of C++/CLI

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Que signifie mapper... ?

    Est-ce que c'est modifier les fichiers C++ pour les rendre compatible dans la DLL avec le C#?

  6. #6
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Non ça veut juste dire qu'il faudra aussi créer un wrapper pour ceux-ci.

    Par exemple si dans une classe C++ "C" tu veux utiliser une méthode qui a comme signature :
    il faudra un wrapper pour "C" donc, mais aussi pour les types "A" et "B".

    Bien sûr inutile de wrapper tous les types, il faut seulement le faire avec ceux exposés par les méthodes C++ manipulées depuis .Net.

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    donc wrapper signifie écrire 2 fichiers supplémentaires .h .cpp (une classe Wrapper ) qui permettre de faire le lien entre ma classe initiale en C++ (dont je ne touche plus au code) et mon projet C# ?

  8. #8
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Non rien à modifier côté C++ natif.

    Juste créer des classes C++/CLI dédiées et qui vont faire les intermédiaires entre C# et le C++ natif.
    Ce sont ces classes qu'on appelle des wrappers car ils encapsulent des classes C++ natives.

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Merci, j'ai compris le principe du Wrapper et j'ai écrit les codes suivants:

    Cpp initiale:
    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
     
    namespace Cpp
    {
    	public struct Triangle
    	{
    		double X0, Y0, X1, Y1, X2, Y2;
    	};
     
    	class CppInitiale
    	{
    		public:
    			CppInitiale();
    			~CppInitiale();
    			void Etape(std::vector<Triangle> *triangle);			
    	}
    }
    CppWrapper:
    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
     
    namespace CppWrapper
    {
    	Class CppWraper
    	{
    		private:
    			Cpp::CppInitiale* pClass;
    		public:
    			CppWrapperclass();
    			{
    				pClass=new Cpp::cppInitiale();
    			}
    			~CppWrapperClass(){};	
    			void Etape(std::vector<Cpp::Triangle> *triangle)
    			{
    				pClass->Etape2(pTriangle);
    			}
    	}
    }
    C#:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace Projet
    {
    	private void Button3Click(object sender, EventArgs e)
    	{
    		CppWrapper.CppWrapperclass obj=new CppWrapper.CppWrapperclass();
    		Type *instance=new type(); // ligne ?
    		obj.Etape(ref instance);   // ligne ?
    	}
    }
    Malheureusement, je n'arrive pas à trouver le code pour utiliser la méthode "Etape" dans mon C#.

    En effet je souhaite utiliser un tableau de dimension variable donc j'ai pris des vector en C++, mais je ne sais pas quelle est la correspondance en C# -> ?

    Comment faire ?

  10. #10
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Tout dépend de ce que tu comptes en faire.

    Si tu as besoin de l'aspect dynamique, i.e. des éléments seront ajoutés/retirés alors tu peux utiliser une List<Triangle>.
    Sinon un simple Triangle[] fera l'affaire.

    Les deux implémentant IList<Triangle> tu peux faire un peu d'abstraction.

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    J'ai modifié mon code C# en:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    namespace Projet
    {
    	private void Button3Click(object sender, EventArgs e)
    	{
    		CppWrapper.CppWrapperclass obj=new CppWrapper.CppWrapperclass();
    		List<Triangle> t=new List<Triangle>(); 
    		obj.Etape(ref t);   // bug !
    	}
    }
    J'obtiens un bug: unknow method...

    J'ai pas tous saisie je pense, qu'est-ce qu'il faut écrire ou modifier ?

    Merci d'avance

  12. #12
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Au moins 2 soucis :
    - ta struct native Triangle n'a apparemment pas été mappée en .Net,
    - ton wrapper C++/CLI doit aussi utiliser une List<Triangle> qu'il convertira en std::vector<Triangle> pour le transférer au C++ natif.

  13. #13
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    1- Qu'est ce qu'il faut écrire modifier pour "mapper" ma structure Triangle en .net, car je ne comprends pas ce terme ?

    2- Si j'utilise List<Triangle> dans mon Wrapper, je ne sais pas quel #include écrire qui reconnaitra ma List ?

  14. #14
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Quelqu'un a un exemple de code pour "mapper" ma structure ?

  15. #15
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Voilà à quoi ton wrapper devrait ressembler :

    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
    #include "CppInitiale.h"
     
    using namespace System::Collections::Generic;
     
    namespace CppWrapper
    {
    	public value struct Triangle
    	{
    		public: double X0, Y0, X1, Y1, X2, Y2;
    	};
     
    	public ref class CppWrapperClass
    	{
    		private:
    			Cpp::CppInitiale* pClass;
    		public:
    			CppWrapperClass()
    			{
    				pClass = new Cpp::CppInitiale();
    			}
    			~CppWrapperClass(){}
    			void Etape(List<Triangle>^ triangles)
    			{
    				std::vector<Cpp::Triangle> *pTriangle = new std::vector<Cpp::Triangle>();
     
    				for (int i = 0; i < triangles->Count; ++i)
    				{
    					Cpp::Triangle triangle;
    					triangle.X0 = triangles[i].X0;
    					// ...
     
    					pTriangle->push_back(triangle);
    				}
     
    				pClass->Etape(pTriangle);
    			}
    	};
    }
    J'ai recréé une version managée de la struct native.

    Côté C# on n'utilise que les types managés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CppWrapperClass obj = new CppWrapperClass();
     
    List<Triangle> triangles = new List<Triangle>
    {
    	new Triangle { X0 = 123 },
    	new Triangle { X0 = 456 },
    	new Triangle { X0 = 789 }
    };
     
    obj.Etape(triangles);

  16. #16
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Super, merci beaucoup de ton aide, je vais pouvoir avancer.

    Je reviens sur SWIG sinon, c'est un programme qui écrit automatiquement des Wrapper, c'est ça ?

  17. #17
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui exactement pour SWIG il se charge de la tuyauterie intermédiaire.

    Comme tu le vois sur un wrapper le travail n'est pas énorme mais avec des dizaines surtout s'ils évoluent avec le temps ça devient vide un cauchemar à maintenir. :/
    D'où SWIG qui d'ailleurs permet l'interop avec C++ natif depuis bien d'autres langages, c'est un peu une plateforme universelle.

  18. #18
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 107
    Points : 66
    Points
    66
    Par défaut
    Merci encore.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Interfaçage avec explorateur Windows
    Par marcouille49 dans le forum SharePoint
    Réponses: 4
    Dernier message: 24/09/2008, 16h38
  2. Réponses: 6
    Dernier message: 04/01/2008, 11h47
  3. Interfaçage avec SAP
    Par cbleas dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 01/12/2007, 10h00
  4. interfaçage avec terminal portable
    Par azg33 dans le forum 4D
    Réponses: 0
    Dernier message: 29/11/2007, 09h40
  5. Interfaçage avec les API de cdrtools
    Par jeanbi dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 17/07/2004, 16h35

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