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

  1. #1
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    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 sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 455
    Points : 24 867
    Points
    24 867
    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 habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    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 habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    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
    Points : 3 766
    Points
    3 766
    Par défaut
    Salut Feneck91
    Un Tuto sur le site pour creer une base paradox avec C++ Builder
    --
    Plutot que d'essayer de réinventer la roue, apprenons à nous en servir

  6. #6
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    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.

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Bref, un mauvais produit et un mauvais support :-(
    Feneck91, avant de raler renseigne toi !
    Borland C++ 5 date au moins de 1999, c'est obselète ! Paradox tout autant !
    Aujourd'hui c'est C++ Builder RAD Studio XE, ça doit être la version 14 !

    Borland ne s'occupe plus de C++ Builder depuis au moins 4 ans, sission des activités Dev et Proj, création de CodeGear qui fut racheté par Embarcadero !
    Entre temps Borland a perdu de sa superbe et a été racheté par Micro Focus, n'essaye même pas de parler avec eux de C++ Builder, il ne connaisse pas !
    Tu utilises une version dépassée qui n'est plus maintenu !
    Tu veux donc contacter une société qui n'existe plus vraiment pour un produit qui est obselète ! C'est assez osé ! euh ou totalement stupide ?

    Enfin, la différence d'execution entre sans ou avec Paquets, c'est la gestion de la mémoire (RTL Dynamique) ainsi que les appels aux fonctions de la VCL !
    Ce n'est pas anodin !

    Cela influence aussi la façon dont remonte les erreurs, de plus, une erreur peut survenir lors de la remontée de Paquet à Paquet, donc cette erreur en provoque une autre qui devient "incontrôlable", c'est l'OS qui finit par raler)
    Cela peut-être à cause d'un adressage incorrect ou des problèmes de droits sur la mémoire lorsque l'on utilise une DLL en dehors de contexte habituel, heureusement puisque Java est censé être indépendant de la machine, il serait normal que le lancement de DLL soit limitée (et protégée)

    Exemple
    Essaye de lancer une DLL par Script PHP éxécuté par un Navigateur, tu auras droits à de belle erreur 5 "Accès Refusé" sur cette opération d'accès aux API (Thread, signaux, mémoire...) puis lance le même script via PHP.exe, cela passe tout seul !
    l'OS fait un petit gaffe à qui lance quoi !

    Enfin, une base Paradox peut s'attaquer via JDBC-ODBC, tu peux très bien installer le BDE, créer un alias ODBC sur le Driver Paradox et passer par un mode full SQL (très limité, cela reste Paradox !)

    Pour le %s
    Voir tes appels à Format et à Filter !

    Je suppose que pour le moment, ton développement n'était qu'une phase d'étude de faisabilité pour ton projet pour déterminer quelle technologie tu vas utiliser pour la réalisation de celui-ci ? Non ! Oh !
    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

  8. #8
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Non, ce projet n'est hélas pas en phase d'étude. Je suis obligé d'utiliser CE format PARADOX car c'est pour faire une conversion d'un fichier au format X vers ce format de base de données Paradox dont le résultat est utilisé par des applications tierce qui prennent ce fichier paradox en entré.
    Peut-être que Borland n'aurait pas pu me renseigner car le produit n'est plus supporté mais la demande d'informations sur le site de Borland n'abouti jamais http://www.borland.com/fr/company/co...sp?formid=info et c'est ça que je reproche...
    une base Paradox peut s'attaquer via JDBC-ODBC
    Oui seulement pour moi, on me donne le nom du fichier DB à construire et je crée et la base de données (structure) et les données de la base de données, donc l'utilisation via ODBC ne peut pas fonctionner.
    Concernant les problèmes de droits, ça ne peux pas être cela car un EXE borland qui charge la DLL et crée la BDD fonctionne, le même code mais un avec un exécutable MinGW qui charge la DLL ne fonctionne pas, comme si il fallait des initialisations spéciales.
    Normalement une DLL est une librairie dynamique partagée et normalement autonome, elle ne doit pas et ne devrait donc jamais dépendre du compilateur qui a créé l'exécutable qui la charge !
    En gros je n'ai jamais vu dans des projets "création d'une DLL QUE pour mon environnement" et là c'est un peu le cas.

    Mais bon, on s'éloigne du débat, je comprend que tu défendes Borland que j'ai beaucoup utilisé à l'époque de Borland C++ 3.1 sous Ms-Dos et que l'on trouvait génial !
    La question est : y-a-t-il quelqu'un qui a déjà rencontré ce genre de problème et comment le solutionner ?

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Oui seulement pour moi, on me donne le nom du fichier DB à construire et je crée et la base de données (structure) et les données de la base de données, donc l'utilisation via ODBC ne peut pas fonctionner.
    Paradox via ODBC accepte le SQL, donc si tu fournis le répertoire dans la chaine de connexion

    Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="CollatingSequence=ASCII;
    DBQ=C:\DOCUMENTS AND SETTINGS\TOTO;DefaultDir=C:\DOCUMENTS AND SETTINGS\TOTO;
    Driver={Microsoft Paradox Driver (*.db )};DriverId=538;FIL=Paradox 5.X;FILEDSN=C:\Documents and Settings\toto\TotoDB.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;
    ParadoxNetPath=C:\WINDOWS\system32;ParadoxNetStyle=4.x;
    ParadoxUserName=admin;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;"
    Et que tu utilises le SQL, certe limité mais créera bien tes fichiers

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE "employes.db"
    	(
    	NOM CHAR(20),
    	PRENOM CHAR(15),
    	NO_DEPT SMALLINT
    	)

    Sinon, télécharge une trial de XE, c'est plus récent, cela supporte encore le BDE et Paradox !
    Vérifie si cela fonctionne mieux (idem, jouer avec les paquets et de RTL Dynamique)

    As-tu essayé un arnaque ?
    une DLL qui lance un EXE ?
    As-tu essayé de débugger chaque point, un par un ? chaque fonction que tu utilises ?

    Perso, j'ai fourni DLL (stdcall) et DLL (COM, safecall) pour des intégrateurs en PHP, VB.NET, C#, PowerBuilder, Navision... je n'ai jamais ce genre de problème avec Delphi (TTable = VCL = Delphi)
    Mais je fournissais des DLL autonomes sans paquets !
    Je n'ai pas eu ce problème et j'ai utilisé, du TTable, TMyQuery, TADOQuery... en fonction des projets ou employeurs !
    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

  10. #10
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Sinon, télécharge une trial de XE, c'est plus récent, cela supporte encore le BDE et Paradox !
    Vérifie si cela fonctionne mieux (idem, jouer avec les paquets et de RTL Dynamique)
    S'ilfaut acheter cette version ce sera non car ce n'est pas du tout budgetisé dans le travail à faire, donc hélas cette solution n'est pas envisageable.
    As-tu essayé un arnaque ?
    une DLL qui lance un EXE ?
    Je me dirige en effet vers ce genre de solution boiteuse mais qui marcherait...
    As-tu essayé de débugger chaque point, un par un ? chaque fonction que tu utilises ?
    Impossible de débugger ma DLL à partir de l'exe, BC++ ne veut pas débugger dans la DLL, il fait un "step" et c'est tout, je ne peux donc rien débugger. Toutefois, en modifiant le code de la DLL, c'est certain, c'est dans le new TTable(NULL) que ça crash.
    Perso, j'ai fourni DLL (stdcall) et DLL (COM, safecall) pour des intégrateurs en PHP, VB.NET, C#, PowerBuilder, Navision... je n'ai jamais ce genre de problème avec Delphi (TTable = VCL = Delphi)
    Mais je fournissais des DLL autonomes sans paquets !
    Quand je fais cela, ça ne fonctionne plus ni sous Borland, ni sous MinGW...
    Je pense que la solution doit être toute conne, genre une ligne ou un option de compilation, un alignement à définir, un truc bête mais chiant à trouver...
    C'est pas possible qu'il faille obligatoirement utiliser un exe Borland, il y aurait plus de "trace" sur ce genre de problèmes sur le net et là, je n'ai trouvé aucun problème similaire...

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Dommage pour XE mais basé un nouveau développement sur un techno obselète, c'est de tout même pas prudent !

    Je pense surtout qu'il y a peu eu de personnes ayant utilisé JNI avec C++Builder, il existe une version Delphi de JNI dans la Jedi, c'est tout aussi confidentiel !

    sans paquets !
    Quand je fais cela, ça ne fonctionne plus ni sous Borland, ni sous MinGW...
    Il faut que DLL et EXE Borland soit sans paquets et RTL Dynamique décoché, faut pas mélanger ! Sinon tu seras obligé de déployé des DLL et BPL !

    Tu n'échange pas d'objet ou le type AnsiString entre DLL et Java ?
    Tu passe toujours les objets JNI ?

    Tu devrais utiliser un TDatabase comme paramètre pour créer ton TTable, c'est TDatabase que tu renseigne le DatabaseName !

    Perso, lors du DLLEntryPoint, je lance une code de gestion pour isoler chaque thread dont CkeckBDE\CkeckParadox\CheckAlias\...
    Je créais autant d'objet TSession (threadvar) que j'avais de Thread (on ne contrôle pas le nombre de thread d'une appli lorsque l'on fourni un objet à un prestataire, ils sont vicieux certains)
    Evidemement, je nommais (SessionName) moi-même le TSession fraichement créé !
    ! J'avais aussi un TDataModule par thread contenant le TDataBase, TTable, TQuery, bien isolé !

    Faut penser qu'il faut appeler manuellement son DLLEntryPoint lors du 1er chargement de la DLL !

    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
    //----------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------------------------------------
    function CkeckBDE(): Boolean;
    begin
         try
            try
               ThreadSession.Open();
               ThreadSession.Close();
               Result :=  True;
            except
                  Result :=  False;
            end;
         finally
         end;
    end;
     
    //----------------------------------------------------------------------------------------------------------------
    function CkeckParadox(): Boolean;
    var
       DriverList: TStringList;
       i : Integer;
    begin
         Result := False;
         DriverList:= TStringList.Create();
         try
            try
               ThreadSession.Open();
               ThreadSession.GetDriverNames(DriverList);
               for i := 0 to DriverList.Count - 1 do begin
                   if UpperCase(Trim(DriverList[i])) = 'STANDARD' then begin
                      Result := True;
                      Break;
                   end;
               end;
               ThreadSession.Close();
            except
                  Result :=  False;
            end;
         finally
                DriverList.Free();
         end;
    end;
    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

  12. #12
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    J'ai recréé un projet à partir de 0. Non multi-thread (pas besoin).
    Je n'utilise pas VCL.
    J'ai décoché Construire avec les paquets d'exécution
    J'ai décoché utiliser RTL dynamique.
    Et là, ça ne compile plus, j'ai des problèmes de link de type :
    [Lieur Erreur] Unresolved external '__fastcall Dbtables::TTable::~TTable()' referenced from D:\CTSS\DEVC++\PROJET_DB\SOURCES\PARADOXWRITER\OBJ\PARADOXDATABASE.OBJ
    Et de plus, dans le fichier créé il y a le message 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
    //---------------------------------------------------------------------------
    //   Remarque importante à propos de la gestion mémoire de la DLL lorsque votre
    //   DLL utilise la version statique de la Bibliothèque d'exécution :
    //
    //   Si votre DLL exporte des fonctions passant des objets String (ou des structures
    //   ou classes contenant des Strings) comme paramètres ou résultats de fonctions,
    //   vous devez ajouter la bibliothèque MEMMGR.LIB à votre projet DLL et à tous
    //   les projets utilisant la DLL.  Vous devez également utiliser MEMMGR.LIB si
    //   d'autres projets qui utilisent la DLL effectuent des opérations de création ou de
    //   suppression sur des classes non dérivées de TObject, exportées par la DLL.
    //   Ajouter MEMMGR.LIB à votre projet DLL modifie la DLL et les EXE appelant
    //   pour qu'ils utilisent BORLNDMM.DLL comme gestionnaire de mémoire. Dans ce
    //   cas, le fichier BORLNDMM.DLL doit être déployé en même temps que la DLL.
    //
    //   Pour éviter d'utiliser BORLNDMM.DLL, passez les chaînes comme paramètres
    //   "char" ou ShortString.
    //
    //   Si votre DLL utilise la version dynamique de la RTL, vous n'avez pas besoin
    //   d'ajouter MEMMGR.LIB car cela est fait automatiquement.
    //---------------------------------------------------------------------------
    C'est peut-être une piste ! Où ajouter ce MEMMGR.LIB ? J'ai édité le fichier le fichier bpr à la main (et oui, pas très pratique) et j'ai ajouté cette lib
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <LINKER>
        <ALLOBJ value="c0d32.obj $(PACKAGES) $(OBJFILES)"/>
        <ALLRES value="$(RESFILES)"/>
        <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32.lib MEMMGR.LIB"/>
      </LINKER>
    Peut-être une piste ? Tu en penses quoi ? Et quelles lib faut-il ajouter (et comment) pour résoudre les problèmes de link ?

  13. #13
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    J'ai modifié le bpr :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      <LINKER>
        <ALLOBJ value="c0d32.obj $(OBJFILES)"/>
        <ALLRES value="$(RESFILES)"/>
        <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32.lib MEMMGR.LIB Vcl50.lib Vclx50.lib Vcldb50.lib Vclbde50.lib vcldbx50.lib"/>
      </LINKER>
    ça link et le la DLL fait maintenant 600ko, Plus besoin de la dll Borlndmm.dll mais.... résultat identique, ça plante toujours... pourtant je ne dois pas être loin de la solution... J'suis sur que c'est un truc comme ça...

  14. #14
    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
    Points : 3 766
    Points
    3 766
    Par défaut
    Salut Feneck91
    Regarde ce Post tu est peut etre dans ce cas ou il faut convertir le .lib avec "Coff2Omf" voir l'aide en ligne
    --
    Plutot que d'essayer de réinventer la roue, apprenons à nous en servir

  15. #15
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello,

    Tu veux faire une DLL utilisant des objets TTable et autres bidules de la VCL, donc ne décoches pas l'option "Utiliser la VCL"....

    Ensuite, comme l'évoque ShaïLeTroll, faut faire gaffe aux choses que tu vas échanger entre ta DLL et l'exe appelant (arguments de fonctions, objets globaux... je pense aux jobject et aux jstring sur CreateDatabase par exemple)

    Plutôt que de te faire suer avec un gestionnaire de mémoire partagée (partagée entre quoi et quoi d'ailleurs ? vu que ta dll doit être appelée depuis JNI qui de toute façon va utiliser une stratégie d'allocation mémoire encore différente...), tu peux suivre le conseil qui est fourni par Builder:
    // Pour éviter d'utiliser BORLNDMM.DLL, passez les chaînes comme paramètres
    // "char" ou ShortString.
    Donc essaye de tout passer par des char*, des int, des bool...

    Tu as une DLL qui fonctionne lorsqu'elle est utilisée depuis JNI ou un exe compilé avec MinGW. Qu'est-ce qu'elle fait, et qu'est-ce qui fonctionne ? Est-ce qu'elle est compilée avec la VCL (sans la VCL, oublie TTable), et si non, est-ce qu'elle fonctionne avec (sans chercher à utiliser des TTable dans un premier temps) ?

  16. #16
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    J'arrive à linker. C'est au premier new d'une TTable que tout plante...
    Bizarre quand même, qu'est-ce que j'ai oublié ?

  17. #17
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Donc pour ta DLL, tu l'as compilée avec la VCL, en décochant l'utilisation des paquets de construction et de la RTL dynamique, c'est bien ça ?

    Si tu vires ce qui se rapporte aux bases de données, est ce-que dans ta DLL tu peux allouer des AnsiString, bricoler avec des TFileStream (j'essaye d'imaginer des trucs qui permettrait de vérifier que la VCL fonctionne bien) ?

    Dans ton premier message, tu dis
    Il est possible d'appeler les fonctions de la DLL par JNI à partir de Java et cela fonctionne (les appels JNI).
    Que font les fonctions qui ... fonctionnent ?

  18. #18
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par totoche76 Voir le message
    Donc pour ta DLL, tu l'as compilée avec la VCL, en décochant l'utilisation des paquets de construction et de la RTL dynamique, c'est bien ça ?

    Si tu vires ce qui se rapporte aux bases de données, est ce-que dans ta DLL tu peux allouer des AnsiString, bricoler avec des TFileStream (j'essaye d'imaginer des trucs qui permettrait de vérifier que la VCL fonctionne bien) ?

    Dans ton premier message, tu disQue font les fonctions qui ... fonctionnent ?
    J'ai fais plein de choses, avec la RTL + paquets ça plante.
    Maintenant ce qui est mieux c'est que j'ai décoché RTL dynamique ET les paquets, le link directement avec les libs de Borland, du coup ma DLL fait 604ko au lieu de 60 ko mais elle est autonome (enfin je l'espère).
    Les fonctions qui fonctionnent retourne des chaines de caractères (AnsiString converti en jstring par émulation de ce que fait JNI dans le code de l'éxécutable qui appel cette fonction en initialisant des callbacks de conversions), en gros une fonction qui fait GetLastDBError()
    Ce qui plante c'est lorsque je fais new TTable().

  19. #19
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    BORLNDMM.DLL \ MEMMGR.LIB, ce n'est utile que pour le type String, j'espère que l'implementation JNI utilise du char*
    Il faudrait vérifier ce que fait JNI.h, exporte-t-il quelque chose ? variable globale ? objet ?
    Ce n'est qu'un commentaire pour rappeler au développeur de faire un choix stratégique au début du développement, en utilisant AnsiString dans les exports ! ce qu'il ne faut JAMAIS faire à mon avis !
    Et dans ton cas, tu respecte la convention JNI donc pas de AnsiString !

    Mais il est vrai que C++Builder génère des exports inutiles, ce que ne fais pas Delphi !

    Les fonctions qui fonctionnent retourne des chaines de caractères (AnsiString converti en jstring par émulation de ce que fait JNI dans le code de l'éxécutable qui appel cette fonction en initialisant des callbacks de conversions), en gros une fonction qui fait GetLastDBError()
    c'est sur cela qu'il faut travailler, tu peux manipuler en interne des AnsiString mais elle ne doivent pas sortir du programme !
    la conversion AnsiString -> jstring, c'est un CopyMem ? passage de pointeur ?
    Comment gère tu la convertion AnsiString et UTF8 ? tu utilise TUTF8String avec UTF8Decode et UTF8Encode ?

    je suppose que ton code de ta DLL ça ressemble à cela ?

    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
    JNIEXPORT jint JNICALL 
    Java_parser_DB_DBExporter_CreateDatabase(JNIEnv *env, jobject obj, jstring str) 
    {
        // Tu as quoi Ici ?
     
        //-----------------------------
        // Creating database structure
        m_pTable = new TTable(NULL);// <------------ CRASH ICI
     
        // Nom de la Table "C:\Dossier\Fichier.DB" ?
        JBoolean IsCopy;
        m_pTable->TableName = new AnsiString(GetStringUTFChars(env, str, IsCopy));
     
        return 0;
    }
    m_pTable, c'est une variable publique ? globale ? locale ? membre d'un objet vu le préfixe !


    La remarque de Totoche, de tester la VCL par des fonctions de test de faisabilité, est une bonne démarche, voir à partir d'où cela plante !



    Feneck91, retire MEMMGR.LIB, et recompile ton projet !
    Et essaye de vérifier l'objet TSession ! Open, Close, GetConfigMode ... tant que ces méthodes ne fonctionne pas toutes, ce n'est pas la peine d'aller plus loin !
    As-tu ajouté un TDataModule et un TDataBase utilisé comme Owner de ton TTable comme je te l'avais conseillé ?
    Est-ce que DbiInit fonctionne correctement ?
    dans BDE.hpp, tu as toutes les déclarations BDE, normalement, pas de AnsiString, donc pas besoin de BordelMM.dll !

    L'erreur, c'est toujours "Le champ '%s' ne peut être utilisé dans une expression filtre" ?

    Je n'utilise pas VCL.
    Euh, oui et non, tu utilises le TTable, c'est de la VCL (RTL)

    Pour le multi-thread, je ne parle pas de thread interne à ton application, mais des threads Java pouvant appeler ta DLL, là dessus, tu n'as pas le contrôle absolu !

    Blondelle, pour Coff2Omf, c'est valable pour transformer jvm.lib pour C++Builder, mais je ne vois pas en quoi c'est nécessaire pour MEMMGR.LIB, puisque c'est déjà C++Builder qui l'utilise et dans le cas de JNI, il est évident que c'est inutile !
    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

  20. #20
    Membre habitué

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

    Informations forums :
    Inscription : Février 2007
    Messages : 250
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    BORLNDMM.DLL \ MEMMGR.LIB, ce n'est utile que pour le type String, j'espère que l'implementation JNI utilise du char*
    Il faudrait vérifier ce que fait JNI.h, exporte-t-il quelque chose ? variable globale ? objet ?
    Mes fonctions ne font que de la conversion sans rien copier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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);
    }
    Ce code est n'est certainement pas optimal, mais il fonctionne. Ce code est présent dans l'exécutable qui charge la DLL et est appelé via des callbacks initialisés pour simuler les appels par JNI. Il est en effet plus simple de d'abord faire fonctionner l'exe qui charge la DLL puis appel des fonctions pour créer la base de données. Une fois que tout fonctionne l'exe disparait et la DLL sera appelée par JNI, mais tant que àa ne fonctionne pas, pas la peine d'aller plus loin...
    Citation Envoyé par ShaiLeTroll Voir le message
    Ce n'est qu'un commentaire pour rappeler au développeur de faire un choix stratégique au début du développement, en utilisant AnsiString dans les exports ! ce qu'il ne faut JAMAIS faire à mon avis !
    Et dans ton cas, tu respecte la convention JNI donc pas de AnsiString !
    c'est sur cela qu'il faut travailler, tu peux manipuler en interne des AnsiString mais elle ne doivent pas sortir du programme !
    la conversion AnsiString -> jstring, c'est un CopyMem ? passage de pointeur ?
    Comment gère tu la convertion AnsiString et UTF8 ? tu utilise TUTF8String avec UTF8Decode et UTF8Encode ?
    Non, aucune AnsiString ne sort de la DLL. Je ne me suis pas encore pris la tête avec tout cela, tant que le new TTable ne fonctionne pas.
    Citation Envoyé par ShaiLeTroll Voir le message
    Feneck91, retire MEMMGR.LIB, et recompile ton projet !
    Et essaye de vérifier l'objet TSession ! Open, Close, GetConfigMode ... tant que ces méthodes ne fonctionne pas toutes, ce n'est pas la peine d'aller plus loin !
    Pour le moment, plus de DbInit ni rien du tout...
    Mais la semaine dernière j'ai remarqué que la session par défaut ne fonctionnait qu'en partie... Je peux lire certains champs, mais l'accès à ConfigMode en lecture fait planter l'application...
    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    void CParadoxDatabase::CheckDatabaseEngineStart()
    {
        if (!m_bInitDatabaseDone)
        {   // Ask the operating system to allow up to 68 file handles (this is a
            // Requirement of BDE)
            int iHandlesWanted    = 68;
            int iHandlesAvailable = SetHandleCount(iHandlesWanted);
     
            if (iHandlesAvailable < iHandlesWanted)
            {
                char szBuffer[1024];
                sprintf(szBuffer,"Cannot initialize database engine: cannot allow %d handles, only %d avalaible",iHandlesWanted,iHandlesAvailable);
                m_strLastError = szBuffer;
            }
            else
            {
                DBIResult dbiResult = DbiInit(NULL);
                dbiResult = DBIERR_NONE;
                // initializing the driver
                if (dbiResult != DBIERR_NONE)
                {
                    char szBuffer[1024];
                    sprintf(szBuffer,"Cannot initialize database engine: DbiInit failed (return error code: %d )!",(int) dbiResult);
                    m_strLastError = szBuffer;
                }
                else
                {
                    m_strLastError += "Bde Intalled !! -";
     
                    if (Session == NULL)
                    {
                        m_strLastError += "Session is NULL - ";
                    }
                    else
                    {
                        char szBuffer[1024];
                        sprintf(szBuffer,"Session is NOT NULL (%X) -",(int) Session);
                        m_strLastError += szBuffer;
     
                        sprintf(szBuffer,"Sessions count = %d -",(int) Sessions->Count);
                        m_strLastError += szBuffer;
     
                        if (Sessions->Count == 1)
                        {
                            sprintf(szBuffer,"Sessions name = %s (%X) -",Sessions->Sessions[0]->Name.c_str(),(int) Sessions->Sessions[0]);
                            m_strLastError += szBuffer;
                        }
     
                        sprintf(szBuffer,"StartupEvent = %X -",Session->OnStartup);
                        m_strLastError += szBuffer;
    Session->ConfigMode;
     
    //                    new TSession(NULL);
                        //Session->Close();
                        //Session->Open();
     
     
    /*                    sprintf(szBuffer,"TBDEInitProc = %s (%X) -",(int) TBDEInitProc);
                        m_strLastError += szBuffer;
                        */
    /*
                        Sessions.Count
    Session = new TSession();
                        /*
    TSession
    */
                        m_strLastError += "Session ";
                        //Session->Open();
                        //Session->GetConfigMode();
    /*
    try
    {
                        if (Session->ConfigMode.Contains(cfmVirtual))
                        {
                            sprintf(szBuffer,"cfmVirtual,");
                            m_strLastError += szBuffer;
                        }
                        if (Session->ConfigMode.Contains(cfmPersistent))
                        {
                            sprintf(szBuffer,"cfmPersistent,");
                            m_strLastError += szBuffer;
                        }
                        if (Session->ConfigMode.Contains(cfmSession))
                        {
                            sprintf(szBuffer,"cfmSession,");
                            m_strLastError += szBuffer;
                        }
                        m_strLastError += " -";
    }
    catch(...)
    {
    }
    */
    /*
                        if (Session->AutoSessionName)
                        {
                            sprintf(szBuffer,"Session AutoSessionName - Database Count = %d",(int) Session->DatabaseCount);
                            m_strLastError += szBuffer;
                        }
                        else
                        {
                            sprintf(szBuffer,"Session not AutoSessionName - Database Count = %d",(int) Session->DatabaseCount);
                            m_strLastError += szBuffer;
                        }
    */
                    }
     
    /*
                    // enable trace info
                    DbiDebugLayerOptions(DEBUGON | OUTPUTTOFILE | FLUSHEVERYOP,"D:\\DevC++\\Projet DB BC\\Sources\\bin\\TRACE.INF");
     
                    // Open the database - standard database driver (i.e. DBF tables and NDX/MDX indexes)
                    dbiResult = DbiOpenDatabase(NULL,           // Database name - NULL for standard database
                                                NULL,           // Database type - NULL for standard database
                                                dbiREADWRITE,   // Open mode - Read/Write or Read only
                                                dbiOPENEXCL,    // Share mode - Shared or Exclusive (exclusive, or dbiOPENSHARED for shared)
                                                NULL,           // Password - not needed for the STANDARD database
                                                0,              // Number of optional parameters
                                                NULL,           // Field Desc for optional parameters
                                                NULL,           // Values for the optional parameters
                                                m_hDb);         // Handle to the database
    /*
                    if (dbiResult != DBIERR_NONE)
                    {
                        m_strLastError = "Failed to open default database";
                    }
                    else
                    {
                        // set a working directory
                        dbiResult = DbiSetDirectory(m_hDb,"D:\\DevC++\\Projet DB BC\\Sources\\bin");
                        m_bInitDatabaseDone = true;
                    }
                    DbiSetDirectory(m_hDb,"D:\\DevC++\\Projet DB BC\\Sources\\bin");
    */
     
                    m_bInitDatabaseDone = true;
                }
            }
        }
    }
     
    void CParadoxDatabase::Initialize()
    {
        m_pTable = NULL;
    }
     
    void CParadoxDatabase::Uninitialize()
    {
        CloseDatabase();
        if (m_hDb != NULL)
        {
    //        DbiCloseDatabase(m_hDb);
    //        DbiDllExit(); <--- Ne fonctione pas
            DbiExit();
        }
    }
    Citation Envoyé par ShaiLeTroll Voir le message
    As-tu ajouté un TDataModule et un TDataBase utilisé comme Owner de ton TTable comme je te l'avais conseillé ?
    Est-ce que DbiInit fonctionne correctement ?
    dans BDE.hpp, tu as toutes les déclarations BDE, normalement, pas de AnsiString, donc pas besoin de BordelMM.dll !
    Je n'ai pas testé le TDatabase et le TDataModule, il faudrait peut-être que je creuse en effet de ce côté.
    Citation Envoyé par ShaiLeTroll Voir le message
    L'erreur, c'est toujours "Le champ '%s' ne peut être utilisé dans une expression filtre" ?
    Je n'utilise plus que l'exe MinGW donc je n'ai qu'un crash de l'appli, plus d'exception. De toute façon avec l'exe Borland, ça fonctionne donc je ne recherche plus de ce côté, je veux une DLL qui soit appelée par JNI.
    Citation Envoyé par ShaiLeTroll Voir le message
    Euh, oui et non, tu utilises le TTable, c'est de la VCL (RTL)

    Pour le multi-thread, je ne parle pas de thread interne à ton application, mais des threads Java pouvant appeler ta DLL, là dessus, tu n'as pas le contrôle absolu !
    Je me dit que selon les modes de compilation multi-thread ou pas ça peut poser des problèmes, ça se voit sous Visual C++, via Borland C++ Builder je ne sais même pas où est cette option, je pense qu'il faut éditer le bpr à la main et mettre les bonnes options de compilation...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 4 1234 DernièreDernière

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