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 :
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 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(); }
Erreur provoquée sous MinGW :
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; }
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 ?
Partager