none
les librairies refusées par le compilateur: pourquoi? RRS feed

  • Question

  • J'ai introduit l'instruction suivante dans mon programme en suivant l'indication donnée ici dans la rubrique System.Web.Hosting Namespace

    using namespace System::Web::Hosting;

    mais le compilateur refuse ce nom:

    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(20): error C2039: 'Hosting' : n'est pas membre de 'System::Web'
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(20): error C2871: 'Hosting' : un espace de noms avec ce nom n'existe pas

    ??????


    Jean Noël Martin

    vendredi 13 juillet 2012 08:16

Réponses

Toutes les réponses

  • Quand vous compilez du code managé, la compilation et l'édition de lien sont confondus.

    Using, comme en C++ "standard", n'ajoute rien dans les options du linker mais ne sert qu'à simplifier l'écriture du code.

    Le compilateur vérifie que, dans l'ensemble des assemblies donnés en référence, il y a un namespace avec ce nom (plus précisément, si une classe est défini dans un namespace à ce nom). Cela permet de détecter les conflits/ambiguïtés lors que 2 classes portent le meme nom, (via des using namspace de différents pour les ambiguïtés).

    Vous avez donc ce message d'erreur, tout simplement parce qu'aucune de vos classes, ni des classes des assemblies que votre projet référence n'est défini dans le namespace System::Web::Hosting (mais vous devez en avoir dans le namespace System::Web, je crois que l'assembly System.dll en contient).

    Il est facile de confondre assemblies et namespace car ils ont souvent la meme forme.

    Je ne peux pas dire exactement comment résoudre votre problème sans avoir plus de code mais cela ce résumera à ajouter une référence vers un assembly contenant des classes dans ce namespace.

    Par exemple, pour la classe HostingEnvironment ( http://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.aspx ) qui fait partie du namespace incriminé, la dcumentation indique qu'elle fait partie de l'assembly "System.Web (in System.Web.dll)", il faut donc ajouter une référence à cet assembly dans votre projet pour pouvoir vous en servir dans votre code.

    Il suffit de suivre le meme principe pour les classes du namespace que vous utilisez. (Il peut avoir plusieurs assemblies pour un seul namespace).

    L'assembly est un découpage "physique", le namespace un découpage logique.


    Paul Bacelar, Ex - MVP VC++

    vendredi 13 juillet 2012 12:04
    Modérateur
  • mon problème est que la ligne ci dessous n'est pas accepté par le compilateur. j'ai essayé plusieurs namespace sans succès.

         if (FileExists(wsDatabaseName.c_str()) == true)

    et le résutat de la compilation est

    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(464): error C3861: 'FileExists' : identificateur introuvable
    

    Je comprend que les namespace ont une syntaxe un peu particulière. mais je dois savoir m'en servir.


    Jean Noël Martin

    vendredi 13 juillet 2012 15:21
  • La fonction "FileExists" ? Moi je ne connais pas de fonction standard "FileExists", c'est dans quelle librairie, s'il s'agit d'une fonction native ?

    Si c'est le cas, il vous manque le #include correspondant à cette librairie.

    Si c'est une fonction managée, je ne la connais pas. Je connais plutot la méthode statique Exists de la classe File ( http://msdn.microsoft.com/fr-fr/library/system.io.file.exists(v=vs.100).aspx ), dans le namespace Systel.IO dans l'assembly du runtime .NET mscorlib (dans mscorlib.dll).

    Il faudrait donc simplement remplacer "FileExists" par "File::Exists" et, peut-etre convertir votre std::string en String^.

    P.S.: le "== true" est inutile donc inélégant. ;-) (à moins que le format de sortie de "FileExists" soit piégeux.)


    Paul Bacelar, Ex - MVP VC++

    vendredi 13 juillet 2012 16:38
    Modérateur
  • la solution File::exist semble bonne, mais j'ai  un message du compilateur qui me dit erreur de syntaxe ; sur le gcnew et je me demande ou?

     if( m_bServerConnected == true)
        {
    //    IF (The file already does't exist) THEN
    //    {
              // bool File::Exists (String^ virtualPath)
    	  System::String^ VirtualPath = gcnew( (std::wstring)wsDatabaseName.c_str());
    	  if( File::Exists( VirtualPath) == false)
              {
              //      [Construct the database creation request, in "sRequest"]
              //      [Execute the request]
                 memset(sRequest, 0x00, 256);

    J'ai modifié le source pour essayer de clarifier le problème.

              System::String^ VirtualPath;
    	  VirtualPath = gcnew( (std::wstring)wsDatabaseName.c_str());
    	  if( File::Exists( VirtualPath) == false)

    il y a le même diagnostic sur la ligne du gcnew;

    si on retire l'initialisation avec la wstring il met erreur de parenthèse ) alors que l'instruction devient gcnew();

    J'ai donc essayé une autre stratégie basé sur la librairie de msdn qui pose deux problèmes:

    using namespace System;
    using namespace System::IO;
    using namespace System::Runtime::InteropServices;

    (...)

    if( m_bServerConnected == true) { // IF (The file already does't exist) THEN // { //bool File::Exists (String^ virtualPath) System::String^ VirtualPath; int len; VirtualPath = gcnew( System::String^); // public: static void Copy( IntPtr source, array<wchar_t>^ destination, int startIndex, int length); len = wcslen( (wchar_t*)wsDatabaseName.c_str()); Marshal.Copy( VirtualPath, (wchar_t*)wsDatabaseName.c_str(), 0, len); if( File::Exists( VirtualPath) == false) { // [Construct the database creation request, in "sRequest"] // [Execute the request] memset(sRequest, 0x00, 256);

    et là les using sont bien acceptés

    le gcnew génère un nouveau message d'erreur

    et le marshal.Copy en génère 2. J'ai également essayé sans Marshal et Copy n'est alors pas identifié.

    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(356): error C2726: 'gcnew' peut uniquement être utilisé pour créer un objet de type managé
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(359): error C2143: erreur de syntaxe : absence de ';' avant '.'
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(359): error C2143: erreur de syntaxe : absence de ';' avant '.'

    et j'ai également essayé la syntaxe suivante: VirtualPath = gcnew wsDatabaseName.c_str();

    il me répond la même chose avec: VirtualPath = gcnew VirtualPath;

    ou avec VirtualPath = gcnew System::String^;

    mais Marchal::Copy est reconnu:

    Marshal::Copy( VirtualPath, (wchar_t*)wsDatabaseName.c_str(), 0, len);

    J'ai quand même une difficulté pour cette ligne j'ai suivi les conseils du compilateur et je n'y arrive pas. L'indication de la fonction que j'ai mis en commentaire est Copie des données d'un pointeur mémoire non managé dans un tableau de caractères managé.:

              // public: static void Copy( IntPtr source,  array<wchar_t>^ destination, int startIndex, int length);
    	  len = wcslen( (wchar_t*)wsDatabaseName.c_str());
    	  Marshal::Copy(  VirtualPath, 0, wsDatabaseName.c_str(), len);

    J'ai continuer à travailler sur ce sujet et j'ai réduit les messages d'erreurs en castant tout comme une brute:

    Quel que soit le type donné pour la System::String^ le message est le même. Ainsi le code est devenu:

              System::String^ VirtualPath;
    	  array<wchar_t>^ VirtualBuffer;
    	  size_t len;
    	  len = wcslen( (wchar_t*)wsDatabaseName.c_str());
    	  VirtualPath = gcnew System::String;
    	  VirtualBuffer = gcnew array<wchar_t, (int) 1>;
    	  // le prototype décit dans msdn library: public: static void Copy( IntPtr source,  array<wchar_t>^ destination, int startIndex, int length);
    	  // la description de la fonction dans msdn library: Copie des données d'un pointeur mémoire non managé dans un tableau de caractères managé.
    	  // suggestion du compilateur Marshal::Copy(cli::array<Type,dimension> ^,int,System::IntPtr,int) 
    	  Marshal::Copy( VirtualBuffer, (Int32)0, (System::IntPtr)wsDatabaseName.c_str(), (Int32)len);
    	  VirtualPath = (System::String^)VirtualBuffer;

    et les erreurs ont été réduit à ca:

    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(358): error C2512: 'System::String::String' : aucun constructeur par défaut approprié disponible
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(359): error C2748: La création de tableau managé doit posséder une taille de tableau ou un initialiseur de tableau
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(363): error C2440: 'cast de type' : impossible de convertir de 'const wchar_t *' en 'System::IntPtr'
    1>          Aucun opérateur de conversion définie par l'utilisateur disponible qui puisse effectuer cette conversion, ou l'opérateur ne peut pas être appelé
    1>..\..\..\..\DBMS\DBMSManager\src\InterbaseManager.cpp(364): error C2440: 'cast de type' : impossible de convertir de 'cli::array<Type> ^' en 'System::String ^'
    1>          with
    1>          [
    1>              Type=wchar_t
    1>          ]

    il reste que il y a plusieurs problème: les un sont incompréhensibles les autres demandent une fonction que je ne connais pas

    et sur gcnew le lien est celui ci


    Jean Noël Martin













    vendredi 13 juillet 2012 17:42
  • Finalement le code qui compile est celui ci est donné par ce lien

              System::String^ VirtualPath;
    	  VirtualPath = gcnew String(wsDatabaseName.c_str());
    	  if( File::Exists( VirtualPath) == true)


    Jean Noël Martin

    • Marqué comme réponse JeanNoel53 mardi 17 juillet 2012 10:01
    mardi 17 juillet 2012 10:01