Closed mp1609 closed 2 months ago
Hi there,
I got a strange issue when using python4delphi as a DLL. I have a running demo (compiled as "exe" file) which is working:
FYI using the current latest code of this repo.
program ProjectWorking; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes, System.Variants, System.Diagnostics, WinApi.Windows, IOUtils, PythonEngine, VarPyth; {$R *.res} const coPythonFolder = 'python-3.8.3-embed-win32'; type TArrayOfDouble = TArray<double>; var PythonEngine : TPythonEngine; cmd : TStringList; procedure CreatePythonEnvironment; begin end; procedure CreatePyEngine; begin PythonEngine := TPythonEngine.Create(nil); PythonEngine.Name := 'PythonEngine'; with PythonEngine do begin APIVersion := 1013; AutoLoad := False; AutoUnload := true; AutoFinalize := true; UseLastKnownVersion := false; DllName := 'python38.dll'; DllPath := GetCurrentDir + '\' + coPythonFolder; PyFlags := []; end; PythonEngine.LoadDll; end; procedure DestroyEngine; begin PythonEngine.Free; end; procedure demo; stdcall; var foo : Variant; var taps, freq, gain : TArrayOfDouble; begin freq := [0, 0.5, 1]; gain := [0, 1, 0]; try cmd.Clear; cmd.Add('N = [0,1,2,3,4,5,6,7,8,9,10]'); PythonEngine.ExecStrings(cmd); foo := MainModule.N; // foo = OK, I see data of "N" finally end; end; exports demo; var taps : Variant; begin CreatePyEngine; cmd := TStringList.Create; demo; end.
So, when running the code, my variable "foo" is readable:
Now I copy that same code and compile it as DLL:
library ProjectDll; uses System.SysUtils, System.Classes, System.Zip, System.Variants, System.Diagnostics, WinApi.Windows, IOUtils, PythonEngine, VarPyth; {$R *.res} const coPythonFolder = 'python-3.8.3-embed-win32'; type TArrayOfDouble = TArray<double>; var PythonEngine : TPythonEngine; cmd : TStringList; procedure CreatePythonEnvironment; begin end; procedure CreatePyEngine; begin PythonEngine := TPythonEngine.Create(nil); PythonEngine.Name := 'PythonEngine'; with PythonEngine do begin APIVersion := 1013; AutoLoad := False; AutoUnload := true; AutoFinalize := true; UseLastKnownVersion := false; DllName := 'python38.dll'; DllPath := GetCurrentDir + '\' + coPythonFolder; PyFlags := []; end; PythonEngine.LoadDll; end; procedure DestroyEngine; begin PythonEngine.Free; end; procedure demo; stdcall; var foo : Variant; var taps, freq, gain : TArrayOfDouble; begin freq := [0, 0.5, 1]; gain := [0, 1, 0]; try cmd.Clear; cmd.Add('N = [0,1,2,3,4,5,6,7,8,9,10]'); PythonEngine.ExecStrings(cmd); foo := MainModule.N; // foo = is NOT OK - I can not see data of "N" finally end; end; exports demo; var taps : Variant; begin CreatePyEngine; cmd := TStringList.Create; end.
To demonstrate how I call the DLL, here is my "DLL caller":
unit UnitDllCaller; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } dll_demo : procedure; stdcall; public { Public-Deklarationen } end; var Form1: TForm1; FDLLHandle : THandle; implementation {$R *.dfm} procedure loadDLLFunction(var APointer : Pointer; AFnName : String; const ARequired : boolean = true); var fnName : PAnsiChar; begin fnName := PAnsiChar(AnsiString(AFnName)); APointer := GetProcAddress(FDLLHandle, fnName); end; procedure TForm1.Button1Click(Sender: TObject); begin FDLLHandle := LoadLibrary(PWchar('ProjectDll.dll')); if(FDLLHandle > 0) then begin loadDLLFunction(@dll_demo , 'demo'); dll_demo(); end; end; end.
So running DLL caller, is working, but my "foo" variable causes an exception:
Here is also the Delphi project to reproduce this: demo.zip
Anyone got an idea? The python code was always executed without errors. I tried to debug a little bit more:
cmd.Clear; cmd.Add('N = [0,1,2,3,4,5,6,7,8,9,10]'); cmd.Add('f = open("demofile2.txt", "w")'); cmd.Add('f.write(str(N))'); cmd.Add('f.close()');
The written demofile2.txt looks as expected, so it seems that reading the variable back causes an error?!
Actually it does work fine despite inspection of foo not working. See below:
Hi there,
I got a strange issue when using python4delphi as a DLL. I have a running demo (compiled as "exe" file) which is working:
FYI using the current latest code of this repo.
So, when running the code, my variable "foo" is readable:
Now I copy that same code and compile it as DLL:
To demonstrate how I call the DLL, here is my "DLL caller":
So running DLL caller, is working, but my "foo" variable causes an exception:
Here is also the Delphi project to reproduce this: demo.zip
Anyone got an idea? The python code was always executed without errors. I tried to debug a little bit more:
The written demofile2.txt looks as expected, so it seems that reading the variable back causes an error?!