Создание расширения Python с Delphi - PullRequest
3 голосов
/ 23 ноября 2011

Я пытаюсь преобразовать функцию Python в Delphi, используя Python4Delphi (надеюсь, для самообразования и увеличения скорости). Однако я понятия не имею, как это работает с 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, а пользовательский объект)

Я нашел связанный Demo09 из Python4Delphi, но не смог найти никакой помощи, как пройти по этому списку, распаковать кортеж и изменить значение.

Какие-нибудь указатели для документации, создающей расширения?

1 Ответ

6 голосов
/ 24 ноября 2011

Python4Delphi решает проблему загрузки основной DLL-библиотеки Python в программу Delphi, встраивая интерпретатор Python в ваше приложение delphi, но также имеет несколько демонстраций для обратного;написать расширение, используя Delphi.Ниже приведен пример рабочего кода.

Я нашел здесь книгу book , на которой написаны расширения Python с использованием delphi.Страница 469 из Python Programming на Win32, автор Mark Hammond & Andy Robinson (O'Reilly).

Пример скелета DLL для Delphi DLL, который реализует расширение Python, может выглядеть следующим образом, взятый из папки Demo09в дистрибутиве исходного кода Python4Delphi:

Источник файла проекта (.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 (неизменяемая структура данных, аналогичная вектору или массиву).Затем вам нужно проанализировать кортеж, и внутри него будет 1 или более аргументов различных типов.Затем вам придется иметь дело с тем фактом, что каждый элемент внутри передаваемого объекта кортежа может быть целым числом, строкой, кортежем, списком, словарем и т. Д. И т. Д.

Вам понадобитсянаучиться вызывать метод для объекта python, как в коде python: img.dim(), получать элементы из списка и т. д.

Искать, где определено PyArg_ParseTuple (Ctrl-клик по нему) и искать другиеметоды, начинающиеся с префикса Py, которые могут иметь имена вроде PyList_GetItem.Это соглашение об именовании псевдо-ООП, используемое python (PyCATEGORY_MethodName).Это все довольно легко, когда вы видите пример кода.К сожалению, большая часть этого примера кода написана на C.

Вы, возможно, даже могли бы использовать инструмент для автоматического преобразования приведенного выше кода Python в пример кода C, а затем попробовать перевести его на Python, строку за строкой.Но все это звучит как пустая трата времени для меня.

Еще несколько функций Python API для поиска и изучения:

Py_BuildValue - полезно для возвращаемых значений

Py_INCREF и Py_DECREF - необходимо для подсчета ссылок на объект.

Вам необходимо знать все правила памяти и правила владения здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...