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++Builder Discussion :

TADOConnection + Unresolved external


Sujet :

C++Builder

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 34
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par d�faut TADOConnection + Unresolved external
    Bonjour,

    Je travaille actuellement sous C++ Builder 5 et essaie d'impl�menter une classe qui me permettra de me connecter � diff�rentes bases de donn�es pour les besoin de l'application que je r�alise.
    J'ai fait le choix d'une classe statique, � savoir que l'ensemble des attributs et m�thodes sont statiques.

    Mon premier probl�me est que j'obtiens les messages suivants � la compilation :
    [Lieur Erreur] Unresolved external 'Database::cnnSQLBIF' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER5\PROJECTS\DATABASE.OBJ
    [Lieur Erreur] Unresolved external 'Database::cnnSQLData' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER5\PROJECTS\DATABASE.OBJ
    J'ai v�rifi� plusieurs fois si je n'avais pas oubli� un petit quelque chose et, � premi�re vue, il me semble que non.

    Mon deuxi�me probl�me est le fait que lorsque je veux instancier mon objet TADOConnection, je suis cens� faire :
    cnnMDB = new TADOConnection(this);
    J'obtiens alors le message suivant :
    [C++ Erreur] Database.cpp(23): E2297 'this' ne peut �tre utilis� que dans une fonction membre
    Je comprends pourquoi le compilateur me signale cette erreur (c'est logique, vu que c'est du statique, le pointeur this ne fait r�f�rence � rien), je ne peux donc pas faire �a.
    Mais alors, comment dois-je proc�der ? Suis-je oblig� de faire de cette fa�on ? Y a-t-il une alternative ?

    Voici le code pour mieux comprendre et visualiser :

    Database.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
    18
    19
     
    #ifndef DatabaseH
    #define DatabaseH
     
    #include <ADODB.hpp>
     
    class Database
    {
       private:
            static TADOConnection *cnnMDB;
            static TADOConnection *cnnSQLBIF;
            static TADOConnection *cnnSQLData;
       public:
            static bool __fastcall openMDBConnection(String dbName);
            static bool __fastcall openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName);
            static bool __fastcall openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName);
     
    };
    #endif
    Database.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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include "Database.h"
     
    bool __fastcall Database::openMDBConnection(String dbName)
    {
       String cs = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbName;
       // voir message compilo quand commentaire retiré
       //cnnMDB = new TADOConnection(this);
       Database::cnnMDB->CursorLocation = clUseClient;
       Database::cnnMDB->ConnectionString = cs;
       Database::cnnMDB->LoginPrompt = false;
       try { Database::cnnMDB->Connected = true; }
       catch (EADOError *e) { return false; }
     
       return true;
    }
     
    bool __fastcall Database::openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName)
    {
       String cs = "Provider=SQLOLEDB.1;Password=" + pw + ";Persist Security Info=True;" + "User ID=" + userName + ";Initial Catalog=" + dbName;
     
       if(serverNamedPipe != "")
            cs += ";Data Source=" + serverNamedPipe;
       else
            cs += ";Network Address=" + serverAddress + ";Network Library=dbmssocn";
     
       if(serverCustom != "")
       {
            cs = serverCustom;
            cs = StringReplace(cs, "<PW>", pw, TReplaceFlags());
            cs = StringReplace(cs, "<ID>", userName, TReplaceFlags());
            cs = StringReplace(cs, "<DB>", dbName, TReplaceFlags());
       }
     
       if(bForBif)
       {
            // voir message compilo quand commentaire retiré
            //cnnSQLBIF = new TADOConnection(this);
            Database::cnnSQLBIF->CursorLocation = clUseClient;
            Database::cnnSQLBIF->ConnectionString = cs;
            Database::cnnSQLBIF->LoginPrompt = false;
            try { Database::cnnSQLBIF->Open(userName, pw); }
            catch (EADOError *e) { return false; }
     
            return true;
       }
       else
       {
            // voir message compilo quand commentaire retiré
            //cnnSQLData = new TADOConnection(this);
            Database::cnnSQLData->CursorLocation = clUseClient;
            Database::cnnSQLData->ConnectionString = cs;
            Database::cnnSQLData->LoginPrompt = false;
            try { Database::cnnSQLData->Open(userName, pw); }
            catch (EADOError *e) { return false; }
     
            return true;
       }
    }
     
    bool __fastcall Database::openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName)
    {
       bool rc;
     
       rc = openSQLConnection(true, userName, pw, serverNamedPipe, serverAddress, serverCustom, BIFDBName);
       if(rc)
       {
            rc = openSQLConnection(false, userName, pw, serverNamedPipe, serverAddress, serverCustom, DataDBName);
            if(!rc)
                    Database::cnnSQLBIF->Close();
       }
     
       return rc;
    }
     
    #pragma package(smart_init)
    J'ai �galement une autre question :

    Comment acc�der � des composants de ma GUI depuis une autre classe, composants d�clar�s dans la partie __published du .h ?

    Merci d'avance.

  2. #2
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    les membres statiques n�cessitent un emplacement de stockage a mettre dans le .H et le CPP selon ta pr�f�rence

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    TADOConnection* Database::cnnMDB = NULL;
    TADOConnection* Database::cnnSQLBIF = NULL;
    TADOConnection* Database::cnnSQLData = NULL;
    Pourquoi utilises-tu du static ?
    Si tu fais un objet C++ standard, comme c'est le cas, tu peux juste cr�er une variable globale en allocation statique qui te servira de singleton !
    Tu pourras avoir des membres d'instance, c'est plus simple non que de cr�er toutes la classe en static !


    Tu dois mettre NULL comme Onwer,
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
       cnnMDB = new TADOConnection(NULL);
    si il se montre capricieux, cela arrive
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
       cnnMDB = new TADOConnection((TComponent*)NULL);
    Ne pas oublier de faire autant de delete que new dans ta future fonction closeMDBConnection

    Plusieurs questions, dans le m�me sujet, ce n'est pas conforme au r�gles du forum, passons ...

    Si tu veux utiliser les membres d'une classe dans le fichier d'une autre classe, tu dois inclure le .h utilis� dans le fichier .CPP qui l'utilisera !
    C'est la base de l'include !



    Avant d'aller plus loin, il te faudrait revoir les Bases du C++ et C++Builder !
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirm�
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 34
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par d�faut
    Tout d'abord merci d'avoir r�pondu.
    Et un merci de plus car tes conseils quant � mon probl�me de TADOConnection ont port� leurs fruits, �a marche maintenant magnifiquement bien !

    En ce qui concerne l'utilisation des membres de mon autre classe, j'avais d�j� essay� d'inclure le .h, sans succ�s (suis quand m�me pas aussi d�butant que �a ^^). Voici le code :

    Gui.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
    18
    19
    20
    21
    22
    23
    24
    25
     
    #ifndef GuiH
    #define GuiH
     
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ComCtrls.hpp>
    #include <Dialogs.hpp>
    #include <ADODB.hpp>
    #include <Db.hpp>
     
    class TInterface : public TForm
    {
    __published:	// Composants gérés par l'EDI
            TLabel *userNameLabel;
    private:	// Déclarations utilisateur
    public:	// Déclarations utilisateur
            __fastcall TInterface(TComponent* Owner);
    };
     
    extern PACKAGE TInterface *Interface;
     
    #endif
    CmdLine.cpp (l� o� je voudrais pouvoir avoir acc�s au TLabel) :
    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 <vcl.h>
    #pragma hdrstop
     
    #include <IniFiles.hpp>
    #include "CmdLine.h"
    #include "Gui.h"
     
    void __fastcall CmdLine::readSettings()
    {
       String path = ExtractFilePath(Application->ExeName)+"settings.ini";
       TIniFile *settings = new TIniFile(path);
     
       if(settings->SectionExists("init"))
       {
            userNameEdit->Text = settings->ReadString("init", "username", "def");
       }
    }
     
    #pragma package(smart_init)
    Le message d'erreur :
    [C++ Erreur] CmdLine.cpp(16): E2451 Symbole 'userNameEdit' non d�fini

    Merci d'avance.

  4. #4
    Membre Expert
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activit� : Responsable de compte
    Secteur : High Tech - Op�rateur de t�l�communications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Billets dans le blog
    1
    Par d�faut
    Salut
    en principe cela devrait �tre
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    Interface->userNameLabel=settings->ReadString("init", "username", "def");
    cdlt
    vous trouverez mes tutoriels � l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les r�gles du forum

  5. #5
    Membre confirm�
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 34
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par d�faut
    Citation Envoy� par DjmSoftware Voir le message
    Salut
    en principe cela devrait �tre
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    Interface->userNameLabel=settings->ReadString("init", "username", "def");
    cdlt
    Effectivement, cela marche maintenant correctement, merci � toi !


    ShaiLeTroll :
    Quand tu dis :
    "Pourquoi utilises-tu du static ?
    Si tu fais un objet C++ standard, comme c'est le cas, tu peux juste cr�er une variable globale en allocation statique qui te servira de singleton !
    Tu pourras avoir des membres d'instance, c'est plus simple non que de cr�er toutes la classe en static !"


    Tu me conseilles d'utiliser le patron de conception singleton en gros ? J'y avais d�j� pens� mais l'id�e de faire des classes statiques m'a sembl� plus facile au premier abord. Je sais bien que ce n'est pas une "bonne pratique" mais disons que le programme sur lequel je travaille n'a pas vraiment �t� pens� objet mais plut�t proc�dural (je dois en fait r�-�crire et optimiser un programme �crit en VB6 � la base). Quels seraient les avantages � ta proposition ? Je ne suis pas si exp�riment� que �a, toute id�e est bonne � prendre et � creuser.

  6. #6
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    En fait, static, �a te fait faire plus de code !

    tu pouvais faire ceci

    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
    class CDatabase
    {
       private:
            TADOConnection *cnnMDB;
            TADOConnection *cnnSQLBIF;
            TADOConnection *cnnSQLData;
       public:
            CDatabase();
            ~CDatabase();
            bool __fastcall openMDBConnection(String dbName);
            bool __fastcall openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName);
            bool __fastcall openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName);
    };
     
    extern CDatabase MyDatabase;
    dans le CPP, tu une seule variable globale !

    tu peux ainsi utiliser le this au besoin, �a te fait moins de mot cl�, en plus, je trouve l'appel est plus "lisible"
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    CDatabase::openMDBConnection(...);
    devient
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    MyDatabase.openMDBConnection(...);
    et le couple constructeur\destructeur
    tu n'as pas besoin d'y pense avec une variable en allocation statique, le destructeur sera appel� automatiquement et lib�rera tes objets internes !

    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
     
    CDatabase::~CDatabase()
    {
      cnnMDB = NULL;
      cnnSQLBIF = NULL;
      cnnSQLData = NULL;
    }
     
    CDatabase::~CDatabase()
    {
      delete cnnMDB;
      cnnMDB = NULL;
     
      delete cnnMDB;
      cnnSQLBIF = NULL;
     
      delete cnnMDB;
      cnnSQLData = NULL;
    }
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. TADOConnection + Unresolved external
    Par Tenebrous dans le forum C++
    R�ponses: 1
    Dernier message: 15/02/2012, 10h24
  2. unresolved external symbol _IID_IDi
    Par PC23 dans le forum DirectX
    R�ponses: 6
    Dernier message: 05/08/2005, 10h38
  3. PB de buil : unresolved external symbol
    Par dede92 dans le forum Windows
    R�ponses: 8
    Dernier message: 13/12/2004, 11h21
  4. unresolved external symbol _IID_IDirectDraw7
    Par lvdnono dans le forum DirectX
    R�ponses: 2
    Dernier message: 15/06/2004, 21h05
  5. R�ponses: 4
    Dernier message: 23/04/2004, 16h06

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