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 :

new TTable() provoque exception Kernel32 ! [Base de donnée]


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Inscrit en
    Février 2007
    Messages
    253
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Février 2007
    Messages : 253
    Par défaut new TTable() provoque exception Kernel32 !
    Il n'y a pas de trace d'erreur, le new TTable() fait crasher l'application lorsqu'il est applelé dans une DLL non chargée par un exécutable Borland.

    J'ai besoin de créer une base de données paradox et d'écrire des lignes dans cette BDD.
    Ce code a été fait dans une DLL sous Borland C++ 5.0 et fonctionne lorsqu'il est lancé par un EXE créé et compilé sous Borland C++ Builder 5.
    Il est possible d'appeler les fonctions de la DLL par JNI à partir de Java et cela fonctionne (les appels JNI).
    Ce qui ne fonctionne pas c'est la création d'instance de TTable (new TTable) qui plante lorsque la DLL est chargée via :
    • JNI
    • Un exécutable compilé sous MinGW.

    Lorsqu'un exécutable fait le même travail (même code) mais compilé
    sous Borland C++ Builder 5 celà fonctionne.

    Le code créé un objet JNIEnv et JNINativeInterface_ et initialise les callbacks afin de
    "simuler" les appels par JNI Le code contenu dans la DLL créé un singleton
    d'une classe. L'appel de la création de la BDD fait simplement :

    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
    try
    {
        //-----------------------------
        // Creating database structure
        m_pTable = new TTable(NULL);// <------------ CRASH ICI
        return 0;
    }
    catch (Exception &_rException)
    { // Close opened database when error occurs // Record exception error 
        m_strLastError = _rException.Message;
        CloseDatabase();
    }
    catch (...)
    { // Close opened database when error occurs 
      // Record unknonw error 
        m_strLastError = "Unknown error"; 
        CloseDatabase();
    }
    Le code de l'exécutable est le suivant :

    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
    #include <iostream>
    #include <windows.h>
    #include <jni.h>
    #include <string>
     
    using namespace std;
     
    typedef jstring (*GetLastDBError)(JNIEnv *, jobject); typedef jint (*CreateDatabase)(JNIEnv *, 
    jobject, jstring);
     
    #ifdef __cplusplus
    extern "C" {
    #endif
     
    const char * JNICALL GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy)
    {
        return (const char *) str;
    }
     
    void JNICALL ReleaseStringUTFChars(JNIEnv *env, jstring str, const char* chars)
    {
    }
     
    jstring JNICALL NewStringUTF(JNIEnv *_pEnv,const char *_pszString)
    {
        return jstring(_pszString); 
    }
     
    #ifdef __cplusplus
    }
    #endif
     
    int main()
    {
        HINSTANCE hDLL = ::LoadLibrary("ParadoxWriter.dll");
     
        if (hDLL != NULL)
        {
            JNIEnv jniEnvironnement;
            JNINativeInterface_ nativeInterface;
     
            // Création
            memset(&nativeInterface,0,sizeof(JNINativeInterface_));
            memset(&jniEnvironnement,0,sizeof(JNIEnv));
            jniEnvironnement.functions = &nativeInterface;
     
            jobject objObject;
     
            nativeInterface.GetStringUTFChars       = GetStringUTFChars;
            nativeInterface.ReleaseStringUTFChars   = ReleaseStringUTFChars;
            nativeInterface.NewStringUTF            = NewStringUTF;
     
            CreateDatabase lpfProcFctCreateDatabase = (CreateDatabase) 
            ::GetProcAddress(hDLL,"Java_parser_DB_DBExporter_CreateDatabase");
            GetLastDBError lpfProcFctGetLastDBError = (GetLastDBError) 
            ::GetProcAddress(hDLL,"Java_parser_DB_DBExporter_GetLastDBError");
     
            if (lpfProcFctCreateDatabase!=NULL && lpfProcFctGetLastDBError!=NULL)
            {
                jstring strLastError = (*lpfProcFctGetLastDBError)(&jniEnvironnement,objObject); // MARCHE !!
                jint iRet = (*lpfProcFctCreateDatabase)(&jniEnvironnement,objObject,jstring("D:\\Ma_user\\Converters\\Format_DB\\Validation\\TEST_64\\Output\\toto.db")); // --> CRASH
            }
        }
     
        return 0;
    }
    Erreur provoquée sous MinGW :
    In RaiseException () (C:\WINDOWS\system32\kernel32.dll)
    Le même code exécuté sur un exe complié avec Borland C++ Builder 5 fonctionne parfaitement.
    J'ai utilisé DbiInit(NULL); mais ça ne change rien.
    La variable Session est bien initialisée, on peut même avoir accès à ses attributs mais pas tous, l'appel de Session->GetConfigMode() créé le crash. Peut être que lorsqu'un TTable est créée, elle appelle cette méthode ????
    Mais alors pourquoi dans le cas d'un appel par un exe borland cela fonctionne ?

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 078
    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 078
    Par défaut
    Tu utilises la VCL Dynamique ainsi que des Paquets d'éxecution ?
    Mieux vaut décocher les deux pour une DLL utilisés en dehors de Delphi !

    Tu as des DLL comme borlndMM.dll qu'il faut déployer !


    Borland C++ 5.0 et Borland C++ Builder 5, ce n'est pas la même chose, le premier c'est OWL, le second VCL !

    TTable c'est le BDE, c'est bien de la VCL !
    JNIEnv, jobject et jstring, c'est quoi ? du Java, ouch, est-ce que cette library est vraiment compatible avec C++Builder, rien que les alignements si ce sont des struct ?

    Paradox ? tu n'as pas mieux ?
    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é

    Inscrit en
    Février 2007
    Messages
    253
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Février 2007
    Messages : 253
    Par défaut
    C'est Borland C++ Builder 5 que j'utilise.
    Lorsque je décoche "Paquet d'execution" dans les options de Paquets, là cela ne fonctionne plus du tout ! Ni sous Borland, ni sous MinGW !
    Une popup s'affiche avec :
    Exception Exeception dans le module
    ParadoxWriter.dll à 00046BBC.
    C'est quoi la VCL dynamique ? Dans lieur, j'ai décoché Utiliser RTL dynamique.
    Les deux programmes sont lancés sur la même machine avec Borland C++ Builder installé.
    Je penche pour une procédure d'init quelconque qui serait appelée par l'EXE et que forcément l'application générée par MinGW n'appelle pas...

    Borland :


    Bref, rien ne marche !

    S'il y a une autre solution pour créér une base de données paradox (db) sans utiliser Borland je suis preneur !
    J'ai utilisé pxlib sous MinGW, j'arriver à créer la base de données mais quand je rajouter des records dans la seule et unique table créée les soft que j'utilise n'arrive pas à les lire, j'en déduit donc que le format généré par pxlib n'est pas correct et donc que la BDD est conrompue...

    JNIEnv, jobject et jstring, c'est quoi ? du Java, ouch, est-ce que cette library est vraiment compatible avec C++Builder, rien que les alignements si ce sont des struct ?
    Ce sont des éléments passés en paramètres pour faire du JNI. Le premier argument est toujours JNIEnv et le deuxième jobject. J'ai initialisé JNIEnv avec les callbacks qu'il faut pour que cela fonctionne comme si c'était appelé depuis Java. La preuve je récupère bien les objets string. Le problème ne vient pas de cela.
    Paradox ? tu n'as pas mieux ?
    C'est pour la réalisation un convertisseur de fichier dont le format destination est un fichier db (base de données paradox), donc hélas, le choix de la bd n'est pas mon choix et je ne peux pas choisir un autre format...
    Edit : Lorsque je décoche "Paquet d'execution" dans les options de Paquets, l'application lancée à partir de Borland C++ Builder se comporte de façon identique à celle lancée à partir de MinGW : les mêmes instructions font planter le code dans les deux cas ! Peut-être quelque choses à investiguer de se côté.Non ?

  4. #4
    Membre confirmé

    Inscrit en
    Février 2007
    Messages
    253
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Février 2007
    Messages : 253
    Par défaut
    Lorsque je compile l'exécutable sans les paquets...
    Lors de l'instruction ::LoadLibrary une exception est lancée indiquant :
    Le champ '%s' ne peut être utilisé dans une expression filtre et c'est pas très clair, mais les erreurs sont vraiments différentes selon les modes de compilation avec paquet ou pas... que faire ?

  5. #5
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut Feneck91
    Un Tuto sur le site pour creer une base paradox avec C++ Builder

  6. #6
    Membre confirmé

    Inscrit en
    Février 2007
    Messages
    253
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Février 2007
    Messages : 253
    Par défaut
    Merci de ce message, mais la création / mise à jour de la BD paradox par mon code fonctionne très bien quand elle est créée via une exécutable Borland C++ Builder. Mon problème est de faire fonctionner ce même programma lorsqu'il est embarqué dans une DLL : si l'exécutable qui la charge est un exécutable Borland C++ Builder, ça fonctionne, lorsque appelé via un Exécutable MinGW ou via Java (JNI) cela ne fonctionne pas comme s'il manquait des initialisations.
    C'est incompréhensible et très ennervant vis-à-vis de Borland.... impossible d'appeler la hot line ou de poster quoi que ce soit sur leur site...
    Bref, un mauvais produit et un mauvais support :-(

    Si quelqu'un à une solution je suis preneur, même sans Borland !
    J'ai essayé pxlib mais ça n'a pas l'air ok.

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

Discussions similaires

  1. probleme : throw new Exception
    Par anto48_4 dans le forum Langage
    Réponses: 8
    Dernier message: 20/12/2010, 08h24
  2. Composite id provoque exception
    Par Reno17 dans le forum Hibernate
    Réponses: 0
    Dernier message: 18/03/2010, 15h39
  3. Réponses: 5
    Dernier message: 25/08/2008, 10h03
  4. New et ses exceptions
    Par TNT89 dans le forum C++
    Réponses: 7
    Dernier message: 04/11/2007, 18h39
  5. msaccess a provoqué une erreur dans KERNEL32.dll
    Par massol joel dans le forum Access
    Réponses: 12
    Dernier message: 03/04/2006, 14h32

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