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

Interfaces de programmation Oracle Discussion :

[OCILIB] Appel de fonction dans ociliba.dll


Sujet :

Interfaces de programmation Oracle

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    AMOE
    Inscrit en
    Juin 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : AMOE

    Informations forums :
    Inscription : Juin 2008
    Messages : 58
    Points : 36
    Points
    36
    Par défaut [OCILIB] Appel de fonction dans ociliba.dll
    Bonjour,

    j'écrie un programme en c++ sous C::B (débutant ) mais en faisant appel à la dll ociliba en 32bits. A la compilation j'ai une erreur en ligne 47 "error: invalid use of incomplete type 'OCI_Error {aka struct OCI_Error}'"

    Le même programme compilé en static avec appel de OCI_GetLastError fonctionne. Merci de votre aide, je rame...

    Code C++ : 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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    #include "ocilib.h"
    #include "InsORA.h"
    #include "GesErr.h"
    #include "../MesFonctions.h"
    #include <string>
    #include <iostream>
     
    using namespace std;
     
    //constructeur
    InsORA::InsORA(const char* a, const char* b, const char* c, int d) :
        Instance(a),
        Utilisateur(b),
        MdP(c),
        MatriculeAgent(d)
    {
    }
     
    bool InsORA::connexionBase()
    {
        HINSTANCE hinstLib = LoadLibrary(TEXT("ociliba.dll"));
        if (hinstLib == NULL) {
                cout << "ERREUR: impossible de charger la DLL " << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
        cn=NULL;
     
        importF13 ociGetLastError;
        ociGetLastError = (importF13)GetProcAddress(hinstLib, "_OCI_GetLastError@0");
        if (ociGetLastError == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_GetLastError@0'" << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
     
        importF20 ociInitialize;
        ociInitialize = (importF20)GetProcAddress(hinstLib, "_OCI_Initialize@12");
        if (ociInitialize == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_Initialize@12'" << endl;
                FreeLibrary(hinstLib);
                return false;
        }else if(!ociInitialize(NULL, NULL, OCI_ENV_CONTEXT )){
            GesErr::err_handler(ociGetLastError());
            FreeLibrary(hinstLib);
            return false;
        }
     
    /*
     
    ...encore du code...
     
    */
        FreeLibrary(hinstLib);
        return true;
    }
     
    void InsORA::deconnexionBase(){
        //OCI_ConnectionFree(cn);
        //OCI_Cleanup();
    }
     
    string InsORA::getInstance(){return Instance;}
     
    string InsORA::getUtilisateur(){return Utilisateur;}
     
    string InsORA::getMdP(){return MdP;}
     
    OCI_Connection *InsORA::getObjCn(void)
    {
        return this->cn;
    }
     
    void InsORA::Affiche()
    {
        //cout << Instance << ", " << Utilisateur << ", " << MdP << endl;
        cout << endl;
        /*
        cout << OCI_GetVersionServer(cn) << endl;
        cout << "Server major    version : " << OCI_GetServerMajorVersion(cn)<< endl;
        cout << "Server minor    version : " << OCI_GetServerMinorVersion(cn)<< endl;
        cout << "Server revision version : " << OCI_GetServerRevisionVersion(cn)<< endl;
        cout << "Connection      version : " << OCI_GetVersionConnection(cn)<< endl;
        */
    }
     
     //destructeur
    InsORA::~InsORA(){}

    et la classe GesErr

    Code C++ : 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
    #include "ocilib.h"
    #include "GesErr.h"
    #include <string>
    #include <iostream>
    #include <errno.h>
    #include "../MesFonctions.h"
     
     
    using namespace std;
     
    //ctor
    GesErr::GesErr()
    {
    }
     
    void GesErr::err_handler(OCI_Error * err)
    {
     
        HINSTANCE hinstLib = LoadLibrary(TEXT("ociliba.dll"));
        if (hinstLib == NULL) {
                cout << "ERREUR: impossible de charger la DLL " << endl;
                FreeLibrary(hinstLib);
        }
     
        importF16 ociErrorGetOCICode;
        ociErrorGetOCICode = (importF16)GetProcAddress(hinstLib, "_OCI_ErrorGetOCICode@4");
        if (ociErrorGetOCICode == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_ErrorGetOCICode@4'" << endl;
                FreeLibrary(hinstLib);
        }
     
        importF8 ociErrorGetString;
        ociErrorGetString = (importF8)GetProcAddress(hinstLib, "_OCI_ErrorGetString@4");
        if (ociErrorGetString == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_ErrorGetString@4'" << endl;
                FreeLibrary(hinstLib);
        }
     
        importF7 ociErrorGetStatement;
        ociErrorGetStatement = (importF7)GetProcAddress(hinstLib, "_OCI_ErrorGetStatement@4");
        if (ociErrorGetStatement == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_ErrorGetStatement@4" << endl;
                FreeLibrary(hinstLib);
        }
     
        cout << "code  : ORA-" << ociErrorGetOCICode(err) << endl;
        cout << "msg   : " << ociErrorGetString(err) << endl;
        cout << "sql   : " << ociGetSql(ociErrorGetStatement(err)) << endl;
     
     
        FreeLibrary(hinstLib);
     
    }
     
    //dtor
    GesErr::~GesErr()
    {
    }

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    c'est quoi la declaration de "importF16" ?
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    AMOE
    Inscrit en
    Juin 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : AMOE

    Informations forums :
    Inscription : Juin 2008
    Messages : 58
    Points : 36
    Points
    36
    Par défaut
    importF13 est un pointeur de fonction défini dans MesFonctions.h après avoir rechercher le prototype de OCI_GetLastError dans ocilib.h...
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef OCI_Error (*importF13)(void);

  4. #4
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Regarde la déclaration que tu as faites de importF13.
    La fonction retourne OCI_Error et non pas OCI_Error *.
    D'ou le message d'erreur coherent du compilo car OCI_Error est un pointeur opaque.

    Donc corrige la définition de importF13.

    Remarque : Si tu compte faire que du GetProcAddress(), n'inclus pas les header ocilib.h.En effet j'ai fait en sorte que tous les objets publics soient des pointeurs opaques. Donc si tu redéfinis toutes les méthodes de OCILIB et les récupere par du load dynamique de symboles, utilise un void * à la place de OCI_Error * , COI_Connection *, .....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    AMOE
    Inscrit en
    Juin 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : AMOE

    Informations forums :
    Inscription : Juin 2008
    Messages : 58
    Points : 36
    Points
    36
    Par défaut
    Bonjour Vincent,

    je n'ai pu mettre en pratique ta remarque sur la déclaration du pointeur de fonction "importF13" que ce matin...Je passerai à la solution que tu préconises (void * ald OCI_xxx) dans l'étape suivante.

    Pour l'instant, plus d'erreur à la compilation. Mais lorsque j'exécute le programme, il plante sur la connection en ligne 53 et la ligne 70 est inopérante.

    Code C++ : 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
    bool InsORA::connexionBase()
    {
        cout << "Instance : " << Instance << endl;
        cout << "Utilisateur : " << Utilisateur << endl;
        cout << "MdP : " << MdP << endl;
     
        HINSTANCE hinstLib = LoadLibrary(TEXT("ociliba.dll"));
        if (hinstLib == NULL) {
                cout << "ERREUR: impossible de charger la DLL " << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
        //cn=NULL;
     
        importF13 ociGetLastError;
        ociGetLastError = (importF13)GetProcAddress(hinstLib, "_OCI_GetLastError@0");
        if (ociGetLastError == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_GetLastError@0'" << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
     
        importF0 ociInitialize;
        ociInitialize = (importF0)GetProcAddress(hinstLib, "_OCI_Initialize@12");
        if (ociInitialize == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_Initialize@12'" << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
        if(!ociInitialize(NULL, NULL, OCI_ENV_CONTEXT)){
            GesErr::err_handler(ociGetLastError());
            FreeLibrary(hinstLib);
            return false;
        }
     
        importF1 ociConnectionCreate;
        ociConnectionCreate = (importF1)GetProcAddress(hinstLib, "_OCI_ConnectionCreate@16");
        if (ociConnectionCreate == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_ConnectionCreate@16'" << endl;
                FreeLibrary(hinstLib);
                return false;
        }
     
        cout << "Instance : " << Instance << endl;
        cout << "Utilisateur : " << Utilisateur << endl;
        cout << "MdP : " << MdP << endl;
     
        cn = ociConnectionCreate(Instance, Utilisateur, MdP,OCI_SESSION_DEFAULT);
     
        if (cn != NULL){
            cout << "<<< CONNEXION REUSSIE >>>" << endl;
        }else{
            cout << "!!! ERREUR DE CONNECTION !!!" << endl;
            GesErr::err_handler(ociGetLastError());
            return false;
        }
     
        importF14 ociGetVersionServer;
        ociGetVersionServer = (importF14)GetProcAddress(hinstLib, "_OCI_GetVersionServer@4");
        if (ociGetVersionServer == NULL) {
                cout << "ERREUR: impossible de trouver dans la DLL la fonction '_OCI_GetVersionServer@4'" << endl;
                FreeLibrary(hinstLib);
        }
     
        cout << ociGetVersionServer(cn) << endl;
     
        FreeLibrary(hinstLib);
        return true;
    }

    le header de la classe InsORA
    Code C++ : 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
    #ifndef INSORA_H
    #define INSORA_H
     
    #include "ocilib.h"
    #include <string>
     
    class InsORA
    {
        //typedef OCI_Connection tyu;
        public:
            int toto;
            InsORA(const char *a, const char *b, const char *c, int d);
            void err_handler(OCI_Error *err);
            bool connexionBase();
            bool verifAgent();
            void deconnexionBase();
            OCI_Connection *getObjCn(void);
            std::string getInstance();
            std::string getUtilisateur();
            std::string getMdP();
            void Affiche();
            virtual ~InsORA();
        protected:
        private:
            const mtext *Instance;
            const mtext *Utilisateur;
            const mtext *MdP;
            int MatriculeAgent;
            OCI_Connection* cn;
     
    };
     
    #endif // INSORA_H

    Les pointeurs de fonctions :
    Code C++ : 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
    //OCI_INitialize
    typedef  boolean (*importF0)(POCI_ERROR, const mtext *, unsigned int);
    //OCI_ConnectionCreate
    typedef  OCI_Connection * (*importF1)(const mtext *, const mtext *, const mtext *, unsigned int);
    //OCI_StatementCreate
    typedef  OCI_Statement * (*importF2)(OCI_Connection *);
    //OCI_Prepare
    typedef  boolean (*importF3)(OCI_Statement *, const mtext *);
    //OCI_BindInt
    typedef  boolean (*importF4)(OCI_Statement *, const mtext *, int *);
    //OCI_Execute
    typedef  boolean (*importF5)(OCI_Statement *);
    //OCI_ErrorGetOCICode
    typedef  int (*importF6)(OCI_Error *);
    //OCI_ErrorGetStatement
    typedef  OCI_Statement * (*importF7)(OCI_Error *);
    //OCI_ErrorGetString
    typedef  const mtext * (*importF8)(OCI_Error *);
    //OCI_GetSql
    typedef  const mtext * (*importF9)(OCI_Statement *);
    //OCI_GetResultset
    typedef  OCI_Resultset * (*importF10)(OCI_Statement *);
    //OCI_FetchNext
    typedef  boolean (*importF11)(OCI_Resultset *);
    //OCI_GetString
    typedef  const dtext * (*importF12)(OCI_Resultset *,  unsigned int);
    //OCI_GetLastError
    typedef OCI_Error * (*importF13)(void);
    //OCI_GetVersionServer
    typedef const mtext * (*importF14)(OCI_Connection *);
    //OCI_GetServerMajorVersion
    typedef unsigned int (*importF15)(OCI_Connection *);
    //OCI_GetServerMinorVersion
    typedef unsigned int (*importF16)(OCI_Connection *);
    //OCI_GetServerRevisionVersion
    typedef unsigned int (*importF17)(OCI_Connection *);
    //GetVersionConnection
    typedef unsigned int (*importF18)(OCI_Connection *);


  6. #6
    Nouveau membre du Club
    Homme Profil pro
    AMOE
    Inscrit en
    Juin 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : AMOE

    Informations forums :
    Inscription : Juin 2008
    Messages : 58
    Points : 36
    Points
    36
    Par défaut
    Etant donné les erreurs que j'obtenais (passage de paramètres à la fonction ociConnectionCreate que je ne récupérais pas), je suis aller faire un tour vers __stdcall...

    J'ai modifié les pointeurs de fonction en ajoutant juste après typedef le littéral '__attribute__((stdcall))'. Exemple pour ma connexion

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //OCI_ConnectionCreate
    typedef  __attribute__((stdcall)) OCI_Connection * (*importF1)(const mtext *, const mtext *, const mtext *, unsigned int);

    Plus de problème d'exécution.

    Pourtant dans les options de compilations C::B, j'avais mis "-DOCI_API=__stdcall". J'ai dû louper un truc.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    AMOE
    Inscrit en
    Juin 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : AMOE

    Informations forums :
    Inscription : Juin 2008
    Messages : 58
    Points : 36
    Points
    36
    Par défaut
    Je cherche à mettre en application la recommandation donnée dans ce post par Vincent Rogier (les pointeurs opaques) mais sans succès : toutes mes lectures semblent m'éloigner du but. Si quelqu'un a une info ou un exemple, je suis preneur !

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/09/2012, 10h12
  2. Type d'argument pour appel de fonction dans une DLL
    Par Lio590 dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 06/07/2011, 16h28
  3. [WD15] Appel de fonctions dans une DLL
    Par thierrybatlle dans le forum WinDev
    Réponses: 11
    Dernier message: 12/02/2010, 01h46
  4. Appel de fonction dans une DLL
    Par vtk37 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 30/04/2009, 08h58
  5. probleme appel de fonction dans une DLL
    Par sylvain.cool dans le forum C++
    Réponses: 12
    Dernier message: 19/06/2008, 17h00

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