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 :

loader en c++ une dll buildée en C#


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 216
    Par défaut loader en c++ une dll buildée en C#
    Bonjour,

    Je cherche à utiliser une fonction d'une dll (buildée en C#) en c++. Voici la fonction en C#

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    namespace WMIString
    {
        public class WMI
        {
            public string GetString()
            {
                string maString= "";
                //...
                return maString;
            }
        }
    }
    Dans les propriétés du projet, j'ai mis sous l'onglet applications : target framework : ".NET Framework 2". Sous assembly information, j'ai coché "Make assembly COM-visible"
    Dans les build options, j'ai coché, "register for COM interop". Je devrais donc pouvoir utiliser cette dll dans un autre language, non?
    J'ai ensuite builder la dll (appelons la madll.dll) sans erreur

    Je veux ensuite charger cette dll depuis un projet c++ (j'utilise Qt également). Pour cela j'ai défini dans mon .h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef std::string (WINAPIV *WMI_GETSTRING)(VOID);
    et dans mon .cpp je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    HINSTANCE hdll;
    hdll = LoadLibraryW( L"madll.dll" );
    if(hdll) 
    	ui.textEdit->append("madll.dll loaded");
    else
    	ui.textEdit->append("madll.dll not loaded");
     
    WMI_GETSTRING WMIGetString;
    WMIGetString= (WMI_GETSTRING)GetProcAddress( hdll, "GetString");
    if( !WMIGetString)
           ui.textEdit->append("cannot find function");
    Cela compile, et je peux voir que la dll est bien chargée correctement (le message "madll.dll loaded" s'affiche), cependant la fonction n'est pas trouvée.

    Pourquoi?
    Merci d'avance pour votre aide

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Est-ce que tu as aussi essayé avec la directive #import ? C'est souvent plus simple.

    Edit : Et puis même, si je me souviens bien, on ne peut pas faire des GetProcAddress comme ça avec COM. Il faut plutôt faire qqchose comme :
    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
     
    #import "madll.dll"
    void foo()
    {
       CoComPtr<IWMI> wmi;
       wmi.CoCreateInstance(/* on passe ici le guid de l'objet com */);
     
       BSTR s = wmi->GetString();
    } // release automatique de wmi quand on sort de la portée de foo
     
    int main()
    {
       CoInitialize();
       foo();
       CoUnitialize();
    }

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 216
    Par défaut
    Merci pour ta réponse Arzar,

    Elle m'a permis de trouver un très bon article nommé "how-to-call-a-managed-dll-from-unmanaged-code"

    Voici les principales étapes
    1. Implémenter et builder la dll C# (class library)
    2. générer un fichier clef à l'aide de la commande
    sn.exe -k MyKeyFile.SNK
    3. Ajoute/modifier les lignes suivantes du fichier AssemblyInfo.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [assembly: ComVisible(true)]
    [assembly: AssemblyDelaySign(false)]
    [assembly: AssemblyKeyFile("MyKeyFile.SNK")]
    4. générer un fichier .tlb à l'aide de la commande
    RegAsm.exe [including full path] madll.dll /tlb:madll.tlb /codebase
    5. on peut ensuite utiliser cette dll depuis du code C++ avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Import the type library in DLL
    #import "madll.tlb" raw_interfaces_only
    Salutations

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    A noter qu'en faisant ainsi, tu crées un wrapper COM autour de ta DLL. Ce n'est pas le seul moyen de faire. En effet, tu peux inclure mscoree.h et importer mscorelib.tlb, tu auras ainsi accès à un wrapper com autour du noyau de la CLR, et à partir de ce wrappper tu pourras appeler CorBindToRuntimeEx pour accéder à la clr, et à partir de là, des fonction comme ExecuteInDefaultAppDomain peuvent demander à la CLR de charger une DLL managée spécifique.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2007
    Messages : 13
    Par défaut
    Bonjour,

    Voici mon problème,

    J'ai une DLL en c# compilée avec VS 2010. Je souhaiterais pouvoir l'utiliser depuis du code natif c++ (comme décrit précédemment), mais depuis VS 2005.

    J'ai essayer de plusieurs manière notamment celle ci qui va créer un wrapper C++ sur ma DLL.

    Code de la DLL dllTest.dll (c# VS2010)
    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
     
    using System;
     
    namespace NamespaceDLL
    {
      public class MaDll
      {
        ...
        public static int SimpleTest(int value)
        {
          return ++value;
        }
        ...
      }
    }
    Code du Wrapper wrapper.cpp (C++ VS2010)
    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
     
    #include "stdafx.h"
    #include "wrapperDll.h"
     
     
    #using "..\bin\Debug\dllTest.dll"
     
    using namespace System;
    using namespace NamespaceDLL;
     
    extern "C"
    {
    	__declspec(dllexport) int __cdecl SimpleTest (int value)
    	{
    		MaDll __gc *test;
    		test = new MaDll;
     
    		return test->SimpleTest (value);
    	}
    }
    Application Test natif test.cpp (WIN32 App consol VS2005)
    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
     
    #include "stdafx.h"
     
    using namespace std;
     
    extern "C"
    {
    	int __cdecl SimpleTest(int value);
    }
     
    int _tmain(int argc, _TCHAR* argv[])
    {	
      SimpleTest(100);
     
      return 0;
    }
    Voilà le gros du code. Tous les fichiers sont présents DLL LIB car pas de problème de compilation. Mais à l'exécution il y a une erreur lors de l'appel de la méthode du wrapper qui fait appel à celle de la DLL.

    Quand j'exécute ce que test depuis VS2010 je n'ai aucun problème et j'obtiens le résultat attendu. Mais via VS2005 erreur ...

    Si vous pouvez m'aider ... Merci.

    Saris

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 492
    Par défaut
    C'est quoi comme erreur ?

    Ciblez-vous bien le Framework 2.0 de .Net dans les projets C# et C++/CLI ?

    VS2005-> Framework 2.0

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 18/02/2015, 14h26
  2. Réponses: 9
    Dernier message: 28/01/2014, 22h43
  3. Utilisation d'une dll écrite en delphi 5 dans VB6
    Par Jean-Louis dans le forum Langage
    Réponses: 4
    Dernier message: 05/08/2002, 09h19
  4. Declarer une dll Delphi ?
    Par DelphiCool dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/07/2002, 10h07
  5. Equivalent à ExeName pour une DLL
    Par Smortex dans le forum Langage
    Réponses: 7
    Dernier message: 16/07/2002, 21h07

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