使用Delphi创建Python扩展

时间:2011-11-23 14:47:57

标签: python delphi python4delphi

我正在尝试使用Python4Delphi将Python函数转换为Delphi(为了教育自己并获得速度,我希望如此)。但是我不知道它如何与Delphi和Python一起工作。这是我原来的功能:

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不是python列表,而是自定义对象)

我从Python4Delphi中找到了相关的Demo09,但找不到任何帮助如何通过该列表,解压缩元组并修改值。

创建扩展文档的任何指针?

1 个答案:

答案 0 :(得分:6)

Python4Delphi处理将Python的主DLL加载到Delphi程序中的问题,将Python解释器嵌入到delphi应用程序中,但也有一些反向演示;使用Delphi编写扩展。下面是一些工作示例代码。

我在这里找到了一本书book,用于使用delphi编写python扩展。作者:Win32上的Python编程的第469页,作者:Mark Hammond&安迪罗宾逊(奥莱利)。

实现python扩展的Delphi DLL的示例DLL框架可能看起来像 这,取自Python4Delphi源码分发中的Demo09文件夹:

项目(.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.

实际扩展单元(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.

请注意,可以从python调用的方法只能有参数Self, Args : PPyObject作为参数签名,而Args值是Python元组(类似于向量或数组的不可变数据结构)。然后你必须解析元组,在其中,将有一个或多个不同类型的参数。然后,您必须处理传入的元组对象中的每个项目可以是整数,字符串,元组,列表,字典等等这一事实。

你将需要学习在python代码中调用python对象的方法:img.dim(),从列表中获取项目等等。

查找定义PyArg_ParseTuple之后(按住Ctrl键单击它)并查找以前缀Py开头的其他方法,这些方法可能包含PyList_GetItem这样的名称。这是python(PyCATEGORY_MethodName)使用的伪OOP命名约定。一旦看到一些示例代码,这一切都很简单。遗憾的是,大部分示例代码都在C中。

您甚至可以使用工具将上面的Python代码自动转换为示例C代码,然后尝试逐行将其转换为Python。但这对我来说听起来都是浪费时间。

要查找和学习的更多Python API函数:

Py_BuildValue - 对返回值很有用

Py_INCREFPy_DECREF - 对象引用计数所必需的。

您需要在此处了解所有memory rules, and ownership rules