![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Странные проблемы с классами [D6, WinXP]
SkyRanger © (2005-11-23 03:54:00)Всем привет.
Написал я несколько классов, чтобы облегчить себе работу с модулем Python на делфи...
Вот они:
[code]
{********************************************************}
{ }
{ pyAPI }
{ Copyright (c) 2005 Vasily V. Altunin }
{ }
{ Разработчик : Алтунин Василий }
{ (skyr@users.sourceforge.net) }
{ Модифицирован : 23.11.2005 }
{ Версия : 0.01 }
{ Вы можете изменять и использовать код приведенный }
{ ниже на свое усмотрение, при условии сохранения этого }
{ блока. }
{ }
{********************************************************}
unit pyAPI;
interface
uses
Python, Windows, dialog, SysUtils;
const
METH_VARARGS = $0001;
type
TMethodArray = array[ 0 .. 16000 ] of PyMethodDef;
PMethodArray = ^TMethodArray;
TFuncArray = array[ 0 .. 16000 ] of PPyObject;
TFuncNameArray = array[ 0 .. 16000 ] of PChar;
TPyMethods = class
private
FMethods : PPyMethodDef;
FMethodsCount : Integer;
FAllocatedMethodCount : Integer;
FModuleName : PChar;
FModuleDoc : PChar;
function GetMethod( Index : Integer ) : PPyMethodDef;
public
constructor Create(ModuleName, ModuleDoc : PChar);
destructor Destroy; override;
function AddMethod( AMethodName : PChar;
AMethod : PyCFunction;
ADocString : PChar ) : PPyMethodDef;
procedure Py_InitModule;
end;
TPyScript = class
private
FpyName : PPyObject;
FpyModule : PPyObject;
FpyDict : PPyObject;
public
constructor Create(ScriptName:PChar);
function GetPyModule : PPyObject;
end;
TPyFunction = class
private
FpyModule : PPyObject;
FFuncCount : Integer;
FAllocatedFuncCount : Integer;
FFuncs : TFuncArray;
FFuncNames : TFuncNameArray;
public
constructor Create(pyModule : PPyObject);
function AddFunc( FuncName:PChar ) : PPyObject;
function GetFuncByName(FuncName:PChar) : PPyObject;
function CallFuncByName(FuncName:PChar; FuncArgs: PPyObject) : PPyObject;
end;
Procedure InitPython;
Procedure ExecPythonScript;
Procedure FreePython;
var
DllHeader : HModule;
pyScript : TPyScript;
PyMethods : TPyMethods;
PyFunction : TPyFunction;
PyModule : PPyObject;
implementation
//====================================================================
constructor TPyMethods.Create(ModuleName, ModuleDoc : PChar);
begin
FAllocatedMethodCount:=PYT_METHOD_BUFFER_INCREASE;
FMethodsCount:=0;
FMethods:=PPyMethodDef(AllocMem(SizeOf(PyMethodDef)*(FAllocatedMethodCount+1)));
FModuleName:=ModuleName;
FModuleDoc:=ModuleDoc;
end;
//--------------------------------------------------------------------
destructor TPyMethods.Destroy;
begin
if Assigned(FMethods) then
begin
FMethods := nil;
end;
inherited;
end;
//--------------------------------------------------------------------
function TPyMethods.GetMethod( Index : Integer ) : PPyMethodDef;
begin
Result := @( PMethodArray(FMethods)^[Index] );
end;
function TPyMethods.AddMethod( AMethodName : PChar;
AMethod : PyCFunction;
ADocString : PChar ) : PPyMethodDef;
var
MethodPtr : PPyMethodDef;
begin
Inc( FAllocatedMethodCount, PYT_METHOD_BUFFER_INCREASE );
ReAllocMem( FMethods, SizeOf(PyMethodDef)*(FAllocatedMethodCount+1));
MethodPtr :=@(PMethodArray(FMethods)^[FMethodsCount+1]);
FillChar( MethodPtr^,SizeOf(PyMethodDef)*PYT_METHOD_BUFFER_INCREASE,0);
Result:=GetMethod(FMethodsCount);
Result^.ml_meth:=AMethod;
Result^.ml_name:=AMethodName;
Result^.ml_doc:=ADocString;
Result^.ml_flags := METH_VARARGS;
Inc(FMethodsCount);
end;
//--------------------------------------------------------------------
procedure TPyMethods.Py_InitModule;
begin
Py_InitModule4(FModuleName, PyMethods.FMethods,FModuleDoc,nil,1012);
end;
//====================================================================
constructor TPyScript.Create(ScriptName:PChar);
begin
FpyName := PyString_FromString(ScriptName);
FpyModule := PyImport_Import(FpyName);
Py_DECREF(FpyName);
FpyDict := PyModule_GetDict(FpyModule);
end;
//--------------------------------------------------------------------
function TPyScript.GetPyModule : PPyObject;
begin
Result:=FpyModule;
end;
Digitman (2005-11-23 08:45:00) [21]что показала пошаговая трассировка ?
SkyRanger (2005-11-23 03:55:00) [22]
//====================================================================
constructor TPyFunction.Create(pyModule : PPyObject);
begin
FpyModule:=pyModule;
end;
//--------------------------------------------------------------------
function TPyFunction.AddFunc(FuncName:PChar) : PPyObject;
var
FuncPtr : PPyMethodDef;
begin
FFuncNames[FFuncCount]:=FuncName;
FFuncs[FFuncCount]:=PyObject_GetAttrString(FpyModule,FuncName);
Inc(FFuncCount);
end;
//--------------------------------------------------------------------
function TPyFunction.GetFuncByName(FuncName:PChar) : PPyObject;
var
I : Integer;
begin
for I:=0 to FFuncCount-1 do
if FFuncNames[I] = FuncName then
Result := FFuncs[I];
end;
//--------------------------------------------------------------------
function TPyFunction.CallFuncByName(FuncName:PChar; FuncArgs: PPyObject) : PPyObject;
begin
Result:=PyObject_CallObject(GetFuncByName(FuncName), FuncArgs);
end;
//====================================================================
function Py_Show( self, args : PPyObject ) : PPyObject; cdecl;
begin
ShowMessage( 'args of Show: '+PyString_AsString(PyObject_Str(args)) );
Result := Py_None;
end;
//====================================================================
Procedure InitPython;
var
ScriptName : PChar;
FuncName : String;
S : String;
pValue : PPyObject;
begin
ScriptName:='script';
FuncName := 'multiply';
PythonInit;
PyMethods := TPyMethods.Create('Show', 'Module Documentation');
PyMethods.AddMethod('show',Py_Show,'Proc Doc');
PyMethods.AddMethod('show1',Py_Show,'Proc Doc');
PyMethods.AddMethod('show2',Py_Show,'Proc Doc');
PyMethods.AddMethod('show3',Py_Show,'Proc Doc');
PyMethods.AddMethod('show4',Py_Show,'Proc Doc');
PyMethods.Py_InitModule;
PyScript := TPyScript.Create(ScriptName);
PyModule:=PyScript.GetPyModule;
PyFunction:= TPyFunction.Create(PyModule);
PyFunction.AddFunc('OnPaint');
PyFunction.AddFunc('OnInit');
PyFunction.AddFunc('OnShow');
PyFunction.CallFuncByName('OnInit',nil);
PyFunction.CallFuncByName('OnShow',nil);
pValue := PyFunction.CallFuncByName('OnPaint',nil);
Str(PyInt_AsLong(pValue),S);
Py_DECREF(pValue);
ShowMessage( S );
end;
//====================================================================
Procedure ExecPythonScript;
var
S : String;
pValue : PPyObject;
begin
pValue := PyFunction.CallFuncByName('OnPaint',nil);
Str(PyInt_AsLong(pValue),S);
Py_DECREF(pValue);
ShowMessage( S );
end;
//====================================================================
Procedure FreePython;
begin
PyMethods.Free;
PyScript.Free;
PyFunction.Free;
PythonFree;
end;
//====================================================================
end.
Вот скрипт на питоне который используется для тестирования:
import Show
print Show.__doc__
print Show.__name__
a=3
b=1
print a,b
#Show.show(2,2,2)
#Show.show4(12,12,12)
def OnInit():
Show.show(1,2,3)
a=3
b=3
def OnShow():
Show.show(10,20,30)
a=3
b=3
print "111 Will compute", a, "times", b
def OnPaint():
Show.show(100,200,300)
return 4
Все бы хорошо, если бы не одно НО:
Если я вызываю просто
InitPython;
FreePython;
Все работает как надо, все вызывается и т.д.
Если же я сделаю так:
InitPython;
ExecPythonScript;
FreePython;
Получаю Access Violation на вызове функции:
pValue := PyFunction.CallFuncByName('OnPaint',nil);
При том даже если я удалю подобный вызов из InitPython;ничего не изменяется :(
По-идее все должно работать, но на практике возникают непонятные проблемы... :(
Скрипт Python.pas вы можете скачать здесь - http://skyr.newmail.ru/Python.pas.Это аналог python.h - импорт функций из .dll питона.