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
- необходимо для подсчета ссылок на объект.
Вам необходимо знать все правила памяти и правила владения здесь.