delphi python内嵌,用Delphi创建Python扩展

I'm trying to convert Python function to Delphi using Python4Delphi (to educate myself and to gain speed, I hope). However I've no idea how this works with Delphi and 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)

I found related Demo09 from Python4Delphi, but couldn't find any help how to go thru that list, unpack the tuple and modify value.

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; to write an extension using Delphi. Below is some working example code.

I found a book book reference here to writing python extensions using delphi. Page 469 of the Python Programming on Win32, by Mark Hammond & Andy Robinson (O'Reilly).

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:

Project (.dpr) file source:

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):

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). 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.

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. That is the pseudo-OOP naming convention used by python (PyCATEGORY_MethodName). It's all pretty easy once you see some sample code. Sadly, most of that sample code is in 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. But it all sounds like a waste of time to me.

Some more Python API functions to look up and learn:

Py_BuildValue - useful for return values

Py_INCREF and Py_DECREF - necessary for object reference counting.

You will need to know all the memory rules, and ownership rules here.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值