none
Intégration d'une DLL C++ dans une appli VB.NET RRS feed

  • Question

  • Bonjour,

    Je veux intégrer une DLL en C++ dans mon appli WinForm VB.NET, sous VS2010.

    J'ai donc ajouté un projet C++ à ma solution puis j'ai créé un petit programme en C++. Pour tester.

    La complitation est Ok.

    Dans le projet VB.NET j'ai ajouté une référence à la DLL ainsi créée. Le problème arrive dans le source VB.NET car la directive Imports ne trouve pas la référence à la DLL.

    Comment faire pour accéder à cette DLL ?

    Existe-il un petit tutorial au sujet de l'usage du C++ depuis le code managé de VB.NET (ou C#) ?

    Merci de votre aide.

     


    Alain
    jeudi 24 mars 2011 16:37

Réponses

Toutes les réponses

  • Bonjour,

     

    Est-ce que votre dll c++ est managé ou natif? Il y a une différence entre l'appel des dll .NET et natifs.

     

    Cordialement,

    Alex


    Suivez MSDN sur Twitter 

    vendredi 25 mars 2011 16:11
  • Bonjour Alex,

    Je ne sais pas répondre à cette question...

    je n'ai rien précisé pour qu'elle soit managée ou native lors de sa création.

    Elle comporte deux petites classes comme celle-ci dont voici le .h :

     

    #pragma once
    
    #ifndef _sp
    #define _sp
    
    class sp
    {
    public:
    	sp(void);
    	void putprop (int j);
    	int getprop (void);
    
    	__declspec(property (get = getprop, put = putprop)) int value;
    
    private :
    	int i;
    };
    
    #endif
    
    

     

    et le .cpp

     

    #include "StdAfx.h"
    #include "sp.h"
    
    
    	void sp::putprop (int j) { 
    		i = j;
    	}
    
    	int sp::getprop() {
    		return i;
    	}
    
    	sp::sp(void) {
    		i = 10;
    	}
    
    

     

    Est-ce suffisant pour dire si elle est managée ou native ?

    En fait il n'y a, pour l'instant, que quelques calculs ou affectations mais, à terme, il s'agit de récupérer du code développé sous Unix.

    Alors peut-être bien que native serait le mieux ??

    Merci de votre aide.

     


    Alain
    • Modifié AchLog vendredi 25 mars 2011 17:02 ajout d'info
    vendredi 25 mars 2011 17:00
  • Bonjour AchLog,

    Avez-vous essayé avec l'instruction Declare ?

    voir : http://msdn.microsoft.com/en-us/library/aa243324.aspx


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement. - Best Regards.
    vendredi 25 mars 2011 17:01
  • Résultat de l'essai : "Instruction invalide dans un NameSpace" !

    Merci Michel K pour la suggestion.


    Alain
    vendredi 25 mars 2011 21:08
  • Bonjour,

     

    Pour une dll managée, on utilise la directive Imports.

    Pour une dll non-managée, on utilise <DllImport>.

     

    La plus convenable méthode, à mon avis, est d’utiliser une dll managée.

    Créez un nouveau projet C++ de type CLR->Class Library. Ajoutez votre classe dans ce projet. Dans la même solution, ajoutez votre projet VB.NET et attachez comme référence le projet C++. Ainsi, vous pourrez utiliser Imports et la classe créée dans le dll C++.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur MSDN !

    Windows Phone 7

    Astuces pour Visual Studio 2010

    XNA – Développement jeux vidéo

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, SharePoint, WPF

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     


    Suivez MSDN sur Twitter 

    mardi 29 mars 2011 09:39
  • Merci Alex pour votre réponse.

    Je voudrais tout d'abord essayer "la moins convenable" des méthodes : DllImport.

    Mais j'ai un message d'erreur que je ne sais résoudre.

    Voici le .h d'une classe en C++

     

    // Spores.h
    #pragma once
    #include "sp.h"
    
    #ifndef _Spores
    #define _Spores
    
    	class Spores
    	{
    	public :
    		Spores();
    		int Get(int idx);
    
    	private :
    		int _MaxSeg;		// Nb max de segments par axe
    		sp _s;				// objet de la class sp
    	};
    
    #endif
    
    

     

    et voici son appel en C# (j'ai ajouté une référence à Spores.dll dans le projet C#) :

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ItfSpores
    {
     [DllImport("Spores.dll", EntryPoint = "Spores")]
     public int Spores::Get(int idx);
    
    }
    
    

     

    Mais, après recompilation, VS2010 place une erreur sur le int (derrière public): "Expected class, delegate, interface enum or struct" !

    Comment corriger cela ? Que manque t-il?

    Merci de votre aide.

    Bien cordialement


    Alain
    mardi 29 mars 2011 12:00
  • Votre code n'est pas correct d'un point de vue syntaxique c#.

    "::", cela n'existe pas en c#.

     

    Avec DllImport, vous êtes très bas niveau donc pas d'orienté objet.

    Donc vous ne pouvez pas facilement accéder à des fonction libres C++ sans un 'extern "C"{}', c'est encore plus difficile pour les méthode statiques, et virtuellement impossible pour les méthodes d'instance.

    En C#, il n'y pas de fonctions libres, il faut obligatoirement une classe dans laquelle sera définit la méthode correspondante.

    Comme il ne peut avoir d'instance associée la à méthode, DllImport s'applique uniquement sur des méthodes statiques.

    class XXX {

    [DllImport("Spores.dll", EntryPoint = "Spores")]
    public static extern int Get(IntPtr sporesHandler, int idx);

    }

    Voir l'exemple dans MSDN

    http://msdn.microsoft.com/fr-fr/library/system.runtime.interopservices.dllimportattribute.aspx#Y2049

    Notez bien l'utilisation d'une fonction C (ou une fonction libre C++ avec un mangling C), et le passage d'un handler pour gérer les instances d'objet C++ de manière opaque pour les utilisateurs de la Dll.

    extern "c"

    {

       int Get(void* pSpore, int idx)

       {

          reinterpret_cast<Spore*> ....

       }

    }

     

    Vérifiez aussi que la dll soit "visible" depuis l'exécutable .NET lors de son lancement. (même répertoire ou dans le DllPath).

    Toujours partant pour utiliser la méthode "la moins convenable" ? ;-)


    Paul Bacelar, Ex - MVP VC++
    mercredi 30 mars 2011 00:07
    Modérateur
  • Merci à vous pour ces informations très utiles ; Décisives, même.

    Je me rends à l'évidence. Grace à vos indications j'ai mis en place la solution "la plus convenable", c'est à dire en C++ managé, préconisée par Alex.

    Elle fonctionne ! Comme indiqué, j'ai créé un nouveau projet C++ de type CLR->Class Library dans lequel j'ai placé mes propres classes.

    J'ai ajouté un projet de test en VB.NET qui appelle le code C++.

    Dans un second temps j'ai créé un nouveau projet VB.NET puis j'ai ajouté à la solution le projet C++ ci-dessus. Le fonctionnement est également correct. Donc cela fonctionne, quelque soit le projet de départ dans la solution et je ne comprends pas la raison pour laquelle j'avais initialement ce problème de link, qui m'a amené à m'adresser au forum...

    Mais je fais encore appel à vous car ce code C++ que j'ai écrit doit utiliser des librairies externes C++ Freeware. Celles-ci réalisent essentiellement du calcul numérique sur des images. Je ne sais pas encore si elles sont directement portables sous Windows.

    Avez-vous une expérience et des conseils sur la méthode à utiliser pour les lier à ce projet C++ ?

    Merci encore.

    Bien cordialement


    Alain
    mercredi 30 mars 2011 13:12
  • C'est l'avantage unique du C++/CLI, le fait d'être à la fois un langage .NET, donc facilement utilisable par les autres langage .NET, et d'être du C++ donc pouvant utiliser facilement de dll C ou C++.

    Cette caractéristique ne va pas sans une petite complexité supplémentaire comme les notion de référence managée (MyClass^ toto), mais vous pouvez être confiant de le choix du C++/CLI.


    Paul Bacelar, Ex - MVP VC++
    jeudi 31 mars 2011 00:01
    Modérateur
  • Je ne suis pas sur d'avoir bien saisi cette notion de référence managée...

    A-t-elle un rapport avec l'accès à des dll externes en C++ ? Comment réaliser cela ? Avez-vous un petit exemple ?

    Merci.


    Alain
    jeudi 31 mars 2011 07:20
  • La richesse du C++/CLI, c'est que vous pouvez faire du C++ normale ET créer des classes et des méthodes utilisables depuis d'autres langages .NET.

    Les références managées, c'est plutôt le volet .NET du C++/CLI.

    Pour les aspects C++, le C++/CLI c'est exactement comme le C++ standard.

    Regardez ce tutoriel

    http://nico-pyright.developpez.com/tutoriel/vc2005/interop/


    Paul Bacelar, Ex - MVP VC++
    • Marqué comme réponse AchLog jeudi 31 mars 2011 16:58
    jeudi 31 mars 2011 12:49
    Modérateur
  • Merci Paul pour votre réponse on ne peut plus claire.

    Ce tutoriel est très bien fait.

    Bien cordialement

     


    Alain
    jeudi 31 mars 2011 16:59