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++/CLI Discussion :

Erreur lors d'un appel à une DLL non-managée, à partir d'une appli VB.NET


Sujet :

C++/CLI

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut Erreur lors d'un appel à une DLL non-managée, à partir d'une appli VB.NET
    Bonjour à tous,

    Je développe sous Vista (avec VS2005) une application qui doit permettre de renseigner des métadonnées pour des fichiers (en utilisant le système de propriétés de Vista).

    J'ai donc une interface en VB.NET qui permet d'annoter des fichiers.
    Cette interface appel une DLL écrite en c++ non-managé (qui s'occupe de lire/écrire les propriétés des fichiers).
    L'interface et la DLL non-managés sont évidemment deux projets distincts (je possède le code des deux projets).

    Après avoir compilé la DLL en mode release je la copie dans le répertoire d’exécution de l’interface, puis je compile celle-ci (également en mode release). Lors de l'utilisation de l'interface, j'obtiens l'erreur suivante :
    "Unable to load DLL 'PropertyHelper.dll': The application has failed to start because its side-by-side configuration is incorrect."

    Je précise que la DLL est générée avec un manifeste intégré.

    Merci d’avance pour vos solutions/suggestions !

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    c'est une dll native ? comment tu l'appelles ?
    as-tu essayé de faire un wrapper en C++/CLI ?

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    C’est effectivement une dll native.

    Pour l’appeler en VB.NET j’ai une classe avec des méthodes de classe qui correspondent aux fonctions de la dll native :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Public Class PropertyHelper
        Declare Auto Function nomdunefonction Lib "PropertyHelper.dll" () As …
    End Class
    Puis j’appel les méthodes ainsi : "PropertyHelper.nomdunefonction()"

    J’ai également essayé avec un wrapper C++/CLI, mais j’obtiens la même erreur ("Unable to load DLL 'PropertyHelper.dll': The application has failed to start because its side-by-side configuration is incorrect.").

    Voici le code du wrapper :

    WrapperPropertyHelper.h
    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
     
    #pragma once
    #include "stdafx.h"
     
    using namespace System;
    using namespace System::Runtime::InteropServices;
    #pragma comment (lib, "PropertyHelper.lib")
     
    /* Ici je ne fais qu’importer la fonction "test" de la dll native, 
    qui renvoie simplement une chaine de caractères */
    [DllImport("PropertyHelper.dll")] extern "C" String^ test();
     
    public ref class WrapperPropertyHelper
    {
        public:
        static String^ Wrappertest();
    };
    WrapperPropertyHelper.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "stdafx.h"
    #include "WrapperPropertyHelper.h"
     
    String^ WrapperPropertyHelper::Wrappertest(){
    	return test();
    }
    Le wrapper est généré correctement, la dll native aussi. J'ai créé une interface simpliste qui référence le wrapper, et qui essaye d'utiliser la fonction test(), mais l'erreur survient au niveau de l'appel dans la fonction WrapperPropertyHelper::Wrappertest().

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    tu as les sources de la dll C ?
    Pourquoi ne pas avoir utilisé dllimport dans ton appli vb.net ?

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Tout d'abord merci pour l'attention que vous portez à ce problème.

    Ce n’est pas une DLL C, mais C++.
    J’avais essayé (laborieusement) de passer cette DLL en C++/CLI, mais j’obtenais plein d’erreurs.

    Voici le code de la DLL :

    PropertyHelper.h
    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
     
    #pragma once
     
    #include <shobjidl.h>
    #include <propsys.h>
    #include <propvarutil.h>
    #include <propkey.h>
    #include <strsafe.h>
     
    extern "C" __declspec(dllexport) PWSTR EnumerateProperties(PCWSTR pszFilename);
    extern "C" __declspec(dllexport) PWSTR GetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName);
    extern "C" __declspec(dllexport) HRESULT SetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName, PCWSTR pszValue);
    extern "C" __declspec(dllexport) HRESULT GetPropertyDescription(PCWSTR pszCanonicalName);
    extern "C" __declspec(dllexport) HRESULT GetPropertyStore(PCWSTR pszFilename, IPropertyStore** ppPropertyStore, GETPROPERTYSTOREFLAGS gpsfFlags);
    extern "C" __declspec(dllexport) PCWSTR test();
    PropertyHelper.cpp
    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
     
    #include "StdAfx.h"
    #include "PropertyHelper.h"
     
    extern "C" __declspec(dllexport) PWSTR EnumerateProperties(PCWSTR pszFilename)
    {...}
    extern "C" __declspec(dllexport) PWSTR GetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName)
    {...}
    extern "C" __declspec(dllexport) HRESULT SetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName, PCWSTR pszValue)
    {...}
    extern "C" __declspec(dllexport) HRESULT GetPropertyDescription(PCWSTR pszCanonicalName)
    {...}
    extern "C" __declspec(dllexport) HRESULT GetPropertyStore(PCWSTR pszFilename, IPropertyStore** ppPropertyStore, GETPROPERTYSTOREFLAGS gpsfFlags)
    {...}
    extern "C" __declspec(dllexport) PCWSTR test()
    {
    	return L"abcdefghijklmnopqrstuvwxyz";
    }
    Je n'ai pas mis le code du corps des cinq premières fonctions car il est assez long, et de toute façon un simple appel à la fonction test provoque l'erreur.

    Concernant l'appel à la DLL dans l'interface codée en VB.NET, je me suis référé à cette rubrique sur MSDN : http://msdn2.microsoft.com/fr-fr/lib...y4(VS.80).aspx. D'après celle-ci, il est possible d'utiliser Declare ou DllImportAttribute indifféremment.

  6. #6
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ok, donc, ton projet C++, tu as essayé de le recompiler en utilisant l'option de compilation /clr, pour avoir une dll mixte ?
    ca a donné quoi comme erreurs ?

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Si je mets juste /clr et que je n'essaye pas de convertir les fonctions en code managé (avec des gcnew, des "^", ...) ca ne donne pas d'erreurs de compilation mais quelques warning, tous du même type (C4793: 'vararg' : causes native code generation for function ...). Le projet est généré malgré ces warnings.
    Si je référence la DLL mixte obtenue dans mon application VB.net, je n'ai accès à aucune de ses fonctions (étant donné que celles-ci sont non-managées).

    Je m'aperçois en lisant ton tutorial de migration au c++ managé (http://nico-pyright.developpez.com/t...grationcppnet/) que je pourrais peut-être m'en sortir en ajoutant des fonctions managées dans la DLL, qui agiraient comme un wrapper, chacune transmettant des arguments à une des fonctions non-managée et récupérant une valeur de retour. Est-ce que ca serait faisable ?

  8. #8
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    oui, je pense que ca sera le plus simple

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Cool, je vais essayer ca.

    Dans ton tutorial, tu utilises StringToHGlobalUni pour convertir des String^ en PCWSTR, est ce que tu connaitrais une fonction permettant de faire la conversion inverse (PCWSTR -> String^) ?

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    J'ai donc essayé de rajouter une fonction managé dans la DLL native, en compilant en /clr.

    J'ai rajouté ceci dans PropertyHelper.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public ref class WrapperPropertyHelper
    {
    public:
    	static System::String^ WrapperLocalTest();
    };
    ... et ceci dans PropertyHelper.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    System::String^ WrapperPropertyHelper::WrapperLocalTest(){
    	return gcnew System::String(test());
    }
    La conversion PCWSTR -> String^ se fait en utilisant un constructeur de la classe System::String.

    J'ai régénéré la DLL mixte ainsi obtenue, puis je l'ai référencé dans l'application VB.net, et j'ai essayé d'appeler la fonction WrapperLocalTest(), mais j'obtiens une fois de plus l'erreur "The application has failed to start because its side-by-side configuration is incorrect.".

    Voici le message d'erreur complet : "Could not load file or assembly 'PropertyHelper, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The application has failed to start because its side-by-side configuration is incorrect.".

    J'avoue que je ne saisis pas ce que veux dire le message. "The application" c'est la DLL mixte ?

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    C'est bon, en fait ca marche

    J'ai réussi à utiliser la DLL mixte : je suis reparti du projet initial (le projet donné comme exemple dans le SDK Vista, PropertySystem), j'ai fais quelques modifications, puis j'ai rajouté des fonctions "wrappantes" au sein meme de cette DLL et j'ai généré avec l'option /clr.

    Je ne sais pas si ca a du sens de procéder ainsi, mais en tout cas ca fonctionne. La possibilité de mixer du C++ natif avec du C++/CLI c'est bien sympa .

    Merci beaucoup !
    ++

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 754
    Points
    39 754
    Par défaut
    Je sais, le problème est résolu, mais je continue le débat
    Je suppose que tu utilises des fonctions de l'API Windows Vista pour accéder aux propriétés ? Dans ce cas, il me semble que le plus simple est sans doute de mapper ces fonctions natives directement dans ton code managé avec l'attribut DllImport....

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 8
    Points : 2
    Points
    2
    Par défaut
    Oui, c'est ce que j'avais fais au départ, mais j'avais du faire une mauvaise manip dans les options du projet de la dll et je me suis retrouvé avec l'erreur qui m'a amené ici (The application has failed to start because its side-by-side configuration is incorrect).

    La version avec des fonctions managées dans la dll rendue mixte me convient parfaitement, j'essayerais peut-être de revenir à la solution consistant à mapper les fonctions natives dans le code VB, mais pour l'instant je garde la dll mixte et je me consacrer à autre chose.

    Dernière question : ce me paraît bizarre que les fonctions permettant de gérer les propriétés (les métadonnées) des fichiers sous Vista soient des fonctions "non-managées", qui ne fassent pas partie du Framework... Je suis peut-être passé à coté de certaines classes du Framework (donc managées et utilisable quelque soit le langage VB, C#, C++/CLI) qui permettent de faire ce travail ?

    ++

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/01/2008, 16h39
  2. appeler du .NET depuis une dll non managé
    Par sebs_78 dans le forum VC++ .NET
    Réponses: 1
    Dernier message: 05/12/2007, 09h36
  3. Réponses: 3
    Dernier message: 19/02/2007, 15h07
  4. Dll managé utilise une dll non managé
    Par DAMVAL dans le forum C++/CLI
    Réponses: 3
    Dernier message: 28/11/2006, 10h36
  5. Réponses: 12
    Dernier message: 30/01/2006, 21h13

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