简体   繁体   English

使用Delphi创建Python扩展

[英]Creating Python extension with Delphi

I'm trying to convert Python function to Delphi using Python4Delphi (to educate myself and to gain speed, I hope). 我正在尝试使用Python4Delphi将Python函数转换为Delphi(以教育自己并获得速度,我希望如此)。 However I've no idea how this works with Delphi and Python. 但是我不知道它如何与Delphi和Python一起工作。 Here's my original function: 这是我原来的功能:

def MyFunc(img, curve):
  C = 160
  for i in xrange(img.dim()[0]):
    p = img[i]
    img[i] = (p[0], p[1], p[2] - curve[p[0]] + C)

(Img is not python list, but custom object) (Img不是python列表,而是自定义对象)

I found related Demo09 from Python4Delphi, but couldn't find any help how to go thru that list, unpack the tuple and modify value. 我从Python4Delphi找到了相关的Demo09,但找不到任何帮助如何通过该列表,解压缩元组并修改值。

Any pointers for documentation creating extensions? 文档创建扩展的任何指针?

Python4Delphi handles the problem of loading Python's main DLL into a Delphi program, embedding the Python interpreter into your delphi application, but also has some demos for the reverse; Python4Delphi处理将Python的主DLL加载到Delphi程序中的问题,将Python解释器嵌入到delphi应用程序中,但也有一些反向演示; to write an extension using Delphi. 使用Delphi编写扩展。 Below is some working example code. 下面是一些工作示例代码。

I found a book book reference here to writing python extensions using delphi. 我在这里找到了一本书参考,用于使用delphi编写python扩展。 Page 469 of the Python Programming on Win32, by Mark Hammond & Andy Robinson (O'Reilly). 由Mark Hammond和Andy Robinson(O'Reilly)编写的Win32上的Python编程页面469。

A sample DLL skeleton for a Delphi DLL that implements a python extension might look like this, taken from the Demo09 folder in Python4Delphi source distribution: 实现python扩展的Delphi DLL的示例DLL框架可能如下所示,取自Python4Delphi源代码分发中的Demo09文件夹:

Project (.dpr) file source: 项目(.dpr)文件来源:

library demodll;

{$I Definition.Inc}

uses
  SysUtils,
  Classes,
  module in 'module.pas';

exports
  initdemodll;
{$IFDEF MSWINDOWS}
{$E pyd}
{$ENDIF}
{$IFDEF LINUX}
{$SONAME 'demodll'}

{$ENDIF}

begin
end.

Actual extension unit (module.pas): 实际扩展单元(module.pas):

unit module;

interface
uses PythonEngine;

procedure initdemodll; cdecl;

var
  gEngine : TPythonEngine;
  gModule : TPythonModule;

implementation

function Add( Self, Args : PPyObject ) : PPyObject; far; cdecl;
var
  a, b : Integer;
begin
  with GetPythonEngine do
    begin
      if PyArg_ParseTuple( args, 'ii:Add', [@a, @b] ) <> 0 then
        begin
          Result := PyInt_FromLong( a + b );
        end
      else
        Result := nil;
    end;
end;

procedure initdemodll;
begin
  try
    gEngine := TPythonEngine.Create(nil);
    gEngine.AutoFinalize := False;
    gEngine.LoadDll;
    gModule := TPythonModule.Create(nil);
    gModule.Engine := gEngine;
    gModule.ModuleName := 'demodll';
    gModule.AddMethod( 'add', @Add, 'add(a,b) -> a+b' );
    gModule.Initialize;
  except
  end;
end;

initialization
finalization
  gEngine.Free;
  gModule.Free;
end.

Note that methods that can be called from python can only have parameters Self, Args : PPyObject as their parameter signature, and the Args value is a Python tuple (an immutable data structure similar to a vector or array). 请注意,可以从python调用的方法只能使用参数Self, Args : PPyObject作为参数签名,而Args值是Python元组(类似于向量或数组的不可变数据结构)。 You then have to parse the tuple, and inside it, there will be 1 or more arguments of various types. 然后你必须解析元组,在其中,将有一个或多个不同类型的参数。 You then have to deal with the fact that each item inside the tuple object passed in could be an integer, a string, a tuple, a list, a dictionary, etc etc. 然后你必须处理传入的元组对象中的每个项目可以是整数,字符串,元组,列表,字典等等这一事实。

You're going to need to learn to call method on a python object as in python code: img.dim() , get items from a list and so on. 您将需要学习在python代码中调用python对象上的方法: img.dim() ,从列表中获取项目等等。

Look for whereever PyArg_ParseTuple is defined (ctrl-click it) and look for other methods that start with the prefix Py that might have names like PyList_GetItem . 查找定义PyArg_ParseTuple时间( PyArg_ParseTuple Ctrl键单击它)并查找以可能具有PyList_GetItem等名称的前缀Py开头的其他方法。 That is the pseudo-OOP naming convention used by python ( PyCATEGORY_MethodName ). 这是python( PyCATEGORY_MethodName )使用的伪OOP命名约定。 It's all pretty easy once you see some sample code. 一旦看到一些示例代码,这一切都很简单。 Sadly, most of that sample code is in C. 遗憾的是,大部分示例代码都在C中。

You could probably even use a tool to auto-convert your Python code above into sample C code, then try translating it into Python, line by line. 您甚至可以使用工具将上面的Python代码自动转换为示例C代码,然后尝试逐行将其转换为Python。 But it all sounds like a waste of time to me. 但这对我来说听起来像是浪费时间。

Some more Python API functions to look up and learn: 查找和学习更多Python API函数:

Py_BuildValue - useful for return values Py_BuildValue - 对返回值有用

Py_INCREF and Py_DECREF - necessary for object reference counting. Py_INCREFPy_DECREF -必需的对象的引用计数。

You will need to know all the memory rules, and ownership rules here. 您需要知道所有内存规则和所有权规则

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM