Jump to content
o815

PyBuffer name of variables to read back to delphi?!

Recommended Posts

Hey there,

 

I was using the Python4Delphi library 2 years ago. So lately I decided to update to the latest version of P4D.

I tried the example "35" from github:

https://github.com/pyscripter/python4delphi/tree/master/Demos/Demo35

 

In my python code, I create an array "taps" which I want to read back to delphi.

I dont't get understand how I can access to this varialbe:

np_arr := ExtractPythonObjectFrom(taps);        // np_arr = nil

 

 

So my modified code looks like:

 

const
  N = 100000;

type
 PIntArray = ^TIntArray;
 TIntArray = array[0..N - 1] of Integer;

var
  Sum: Int64;
  np: Variant;
  taps: Variant;
  np_arr: PPyObject;
  PyBuffer: Py_buffer;
  V: Variant;
  I: Integer;

  cmd : TStringList;

begin
  try
    CreatePyEngine;
    try

      cmd := TStringList.Create;
      cmd.Add('from scipy.signal import kaiserord, lfilter, firwin, freqz, firwin2');
      cmd.Add('taps = firwin2(511, [0.0, 0.032, 0.05, 0.07, 1.0], [0.0, 0.0, 15.0, 0.0, 0.0])');
      {         ^
                |____________ I want to access this variable "taps" in delphi }

      PythonEngine.ExecStrings(cmd);  // is executed without errors

      np_arr := ExtractPythonObjectFrom(taps);        // np_arr = nil



//      PythonEngine.PyObject_GetBuffer(np_arr, @PyBuffer, PyBUF_CONTIG);
//      PythonEngine.CheckError;
//      try
//        Sum := 0;
//        for I := 0 to N - 1 do
//          Sum := Sum + PIntArray(PyBuffer.buf)^[I];

      finally
        PythonEngine.PyBuffer_Release(@PyBuffer);
      end;
    finally
      DestroyEngine;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.

 

 

Perhaps someone got the trick, whats wrong in my code?

Share this post


Link to post
Posted (edited)

Your taps Variant has not assigned a value.  You are missing:

 

taps := MainModule.taps;

Edited by pyscripter
  • Like 1

Share this post


Link to post
Posted (edited)

Hey man, thanks this did the trick, cool!

 

 

Hm there is no option to make this a little more generic, meaning:

 

I create a DLL which is using python4delphi, an has following function:

 

 

DLL idea:
 


TDemoInput = record
   varName : string; // the name of variable in python code
   varValue : variant; // value
end;


TDemoOutput = record
   varName : string; // the name of variable in python code
   varValue : variant; // value
end;


function demo(APythonCode : TStrings; AInput : TArray<TDemoInput>; var AOutput : TArray<TDemoOutput> ): integer;
var

 j : integer;

begin

  result := 0; // return code (for erros)


    for j := 0 to length(AInput)-1 do
    begin
      MainModule.<AInput[idx].varName> := AInput[idx].varValue; // pseudo code -> is this possible with RTTI?!
    end;
    
    PythonEngine.ExecStrings(APythonCode);    


    for j := 0 to length(AOutput)-1 do
    begin    
        AOutput[idx].varValue := MainModule.<AOutput[idx].varName> := ; // pseudo code -> is this possible with RTTI?!
    end;
    

end;

 

 

 

Now  I could call one function in dll and execute the same code as in my first post:

 

 

var

cmd : TStringlist;
frequeny : Variant; // array of double
gain : Variant;     // array of double
...

cmd := TStringList.Create;
cmd.Add('from scipy.signal import kaiserord, lfilter, firwin, freqz, firwin2');
cmd.Add('taps = firwin2(511, frequency, gain)');



//DLL call
demo(cmd, frequency, gain);

 


 

 

Edited by o815

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×