Closed
Description
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?!
Metadata
Metadata
Assignees
Labels
No labels