Contexte :
- Windows: Seven/64 bits
- Delphi: XE7 Entreprise
- Gcc : x86_64-7.3.0
- Scilab : version 6.0. 1/64bits
Je suis confronté au problème suivant :
- J’ai une DLL « FrontalScilab » (WIN64, codée en C++) qui exporte une fonction « _lancerSCILAB » capable de charger puis de lancer le « moteur » Scilab, et de lui faire exécuter un JOB.
- J’ai une application « Client_Exe601x64.exe » qui est une application console WIN 64 (codée en C++) qui charge la DLL « Frontal Scilab » et appelle « _lancerScilab »
- J’ai une application « ScilabExe.exe » qui est une application console WIN 64 (codée en Delphi) qui charge la DLL « Frontal Scilab » et appelle « _lancerScilab »
- Lorsque j’exécute « Client_Exe601x64.exe » tout se passe bien.
- Lorsque j’exécute « ScilabExe.exe » j’obtiens une exception « EInvalidOp » lors du démarrage du « moteur » Scilab
Voir l’illustration ci-dessous.
J’ai pu développer l’ensemble logiciel équivalent en WIN 32 sans que cela pose le moindre problème (Frontal Scilab en C++ et Application cliente en Delphi)
Il n’y a strictement aucune différence entre les deux applications consoles, j’aimerais donc comprendre ce que rajoute/ ou enlève le compilateur Delphi et qui conduit
à cette levée d’exception.
Après avoir soumis le sujet dans le Forum Scilab, j'ai procédé à une simplification importante pour me ramener à la situation courante où deux applications consoles
très épurées et strictement identiques (l'une en C++ l'autre en Delphi) ne se comportent pas de la même façon lors de l'utilisation d'une DLL codée en C++.
Bien entendu comme je l'ai expérimenté depuis longtemps en WIN 32 il est très satisfaisant de pouvoir disposer des capacités de calcul de Scilab
dans une fenêtre d'application Delphi
Code source de la DLL
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 #include <stdio.h> #include "call_scilab.h" /* Provide functions to call Scilab engine */ #if defined(__cplusplus) #define FRONTAL_EXPORT extern "C" __declspec( dllexport ) #else #define FRONTAL_EXPORT __declspec( dllexport ) #endif FRONTAL_EXPORT int __cdecl _lancerSCILAB(int * numErr) { printf("Je suis dans la DLL FrontalScilab C++\n"); printf("Je lance ""_lancerSCILAB""\n"); if ( StartScilab(getenv("SCI"),NULL,0) == FALSE ) { fprintf(stderr,"Error while calling StartScilab\n"); return -1; } printf("Envoi du job : ""disp([1,2;3,4]*inv([1,2;3,4]))"" vers Scilab\n"); SendScilabJob("disp([1,2;3,4]*inv([1,2;3,4]));"); printf("Je sors de ""_lancerSCILAB""\n"); return 0; }
Code source de l'application « Client_Exe601x64.exe » en C++
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 #include <windows.h> #include <stdio.h> typedef int __cdecl (* tLanceScilab)(int * numErr); int main(void) { printf("\nApplication(EXE) C++ cliente de la DLL ""FrontalScilab"" en C++\n"); int numErr; HINSTANCE h = LoadLibrary("C:\\Temp\\Exe-Dll-Scilab\\FrontalScilab_601x64.dll"); if (h==0) printf("Echec du chargement de la DLL\n"); if (h!=0) { tLanceScilab lance; lance = (tLanceScilab)GetProcAddress(h, "_lancerSCILAB"); if (lance) { if (lance(&numErr)==0) { printf("Terminaison normale de l'appel ""_lancerSCILAB""" ); } else { printf("Echec dans ""_lancerSCILAB"", num erreur = %3d", numErr); } } else { printf("Fonction inconnue dans la dll : ""_lancerSCILAB"""); } FreeLibrary(h); } }
Code source de l'application « ScilabExe.exe » en Delphi
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 program ScilabExe; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, windows; procedure lancerScilab; type tLance = function(var numErr: integer): integer; cdecl; var h: THandle; lance: tLance; path1: string; numErr: integer; begin writeln(''); writeln('Application(EXE) DELPHI cliente de la DLL "FrontalScilab" en C++'); writeln(''); path1 := 'C:\Temp\Exe-Dll-Scilab\FrontalScilab_601x64.dll'; h := LoadLibrary(PChar(path1)); try if h = 0 then begin writeln('Echec du chargement de la DLL : "' + path1 + '"'); exit; end; lance := GetProcAddress(h, '_lancerSCILAB'); if not assigned(lance) then begin numErr := 200; writeln('Fonction inconnue dans la dll : "_lancerSCILAB"'); exit; end; if lance(numErr) <> 0 then writeln('Echec dans "_lancerSCILAB", num erreur = ', intToStr(numErr)) else writeln('Terminaison normale de l''appel "_lancerSCILAB"' ); finally FreeLibrary(h); end; end; procedure attendre; begin writeln('pause : appuyez sur la touche "Entree" pour continuer...'); readln; end; begin try lancerScilab; except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end.
Partager