Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Странные проблемы с классами [D6, WinXP]


Страницы:   1 2

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;


SkyRanger   (2005-11-25 03:36:00) [1]

Нет, а с чего бы, я же не выполняю кучу операций с плавающей точкой или сортировки, просто классы для интерфейса, кнопочек и окошечек всяких. Потом событие OnPaint при отрисовке чтобы он знал что вызывать. Все хранится в ядре из скрипта вызываются толко функции, так что быстродействие не страдает. Питон сам по себе довольно шустрый...


alex_***   (2005-11-24 09:39:00) [2]

Ну то что можно не перекомпилять ядро это прикольно, конечно, а быстродействие не страдает?


SkyRanger   (2005-11-24 01:05:00) [3]

Например писать скрипт управления сценой 3d движка, описание интерфейса программы на этом движке. Воообще можно сделать много чего интересного. И самое главное не придется пересобирать ядро. Достаточно добавить код в скрипт.

Все очень просто есть возможность вызова как функций определенных в скрипте питона, так и функций определенных в самом движке и импортированых из него посредством специально объявленного модуля...


TUser   (2005-11-23 10:40:00) [4]

А чего такого можно сделать на питоне, чего нельзя на паскале? Чем вызвана необходимость использования всяких экзотических движков?


jack128   (2005-11-23 10:30:00) [5]

SkyRanger ©   (23.11.05 9:50) [12]
Низя я работаю с функциями импортируемыми из DLL, которая написанна на C++ и чтобы потом не ломать голову почему не работает приходится юзать PChar

LOL.  А те не все равно на чем ломать голову - почему не работает при использовании PChar или почему не работает при использовании string ??

И вообще - это полная чушь, что если ипользует dll, писанные С(++), то нельзя использовать string.


alex_***   (2005-11-23 10:10:00) [6]

в смысле чем меньше зависишь от чужого кода, тем лучше. Если висеть на указателях, данные по которым находятся в чужом коде, то неизвестно что там с ними может произойти. Лучше по возможности работать со своей копией.


SkyRanger   (2005-11-23 10:04:00) [7]

Всмысле отлепися? исходников на Дельфи нет и не будет. Это интерпритатор питона + куча полезных вещей...


alex_***   (2005-11-23 09:54:00) [8]

[12] - ну и отлепись чуть от чужой ДЛЛ. скопируй себе строки и работай со своей копией


alex_***   (2005-11-23 09:52:00) [9]

вот скажи, зачем ты строки в виде PChar хранишь? Потом в один прекрасный момент начнешь глюки ловить. и уж лучше сравнивать через StrCmp (не помню точно имя, дельфи не стоит)


SkyRanger   (2005-11-23 09:51:00) [10]

ЮЮ ©

Если очень интересно то смотри модуль:

http://skyr.newmail.ru/Python.pas

Либо доку по Python - www.python.org


SkyRanger   (2005-11-23 09:50:00) [11]

>с полями типа PChar вообще поосторожней. Я бы заменил поля/типы по >возможности с PChar на string

Низя я работаю с функциями импортируемыми из DLL, которая написанна на C++ и чтобы потом не ломать голову почему не работает приходится юзать PChar.

Спасибо за подсказку буду внимательнее...


SkyRanger   (2005-11-23 09:47:00) [12]

Мдааа...
Маразм крепчал.. Это же PChar и как я понял их низя как простые строки сранивать...

function TPyFunction.GetFuncByName(FuncName:PChar) : PPyObject;
var
I : Integer;
begin
for I:=0 to FFuncCount-1 do
  if String(FFuncNames[I]) = String(FuncName) then
    Result := FFuncs[I];
end;

Теперь вроде работает...
Спасибо всем...


alex_***   (2005-11-23 09:46:00) [13]

с полями типа PChar вообще поосторожней. Я бы заменил поля/типы по возможности с PChar на string


ЮЮ   (2005-11-23 09:44:00) [14]

А что за зверь такой PyObject_CallObject?


alex_***   (2005-11-23 09:44:00) [15]

в GetFuncByName сравниваешь указатели, а не содержимое строки. Зачем деражать в TFuncNameArray PChar, не проще string? Посмотри, отрабатывает GetFuncByName(FuncName), или сыпется в нем


SkyRanger   (2005-11-23 09:44:00) [16]

Ого...
Очень интересно... По непонятной причине не проходит сравнение на первый взгляд двух одинаковый строк в этой пресловутой функции... Очень странно. Ща буду искать де косяк. У меня такое первый раз...


Digitman   (2005-11-23 09:39:00) [17]


> при выполенении:
> Result:=PyObject_CallObject(GetFuncByName(FuncName), FuncArgs);
>
>
> ACCESS VIOLATION и все.


и что ? "внутренности" этого вызова (GetFuncByName) пошагово разве нельзя пройти ?


SkyRanger   (2005-11-23 09:32:00) [18]

alex_*** я ничего не предлагаю, а задаю вопрос и надеюсь на ответ, так как я практически все сделал правильно, иначе вообще бы не работало.


SkyRanger   (2005-11-23 09:31:00) [19]

Ничего!

на function TPyFunction.CallFuncByName(FuncName:PChar; FuncArgs: PPyObject) :
при выполенении:
Result:=PyObject_CallObject(GetFuncByName(FuncName), FuncArgs);

ACCESS VIOLATION и все.

Причем все экземпляры классов никуда не деваются и не изменяются вProcedure ExecPythonScript;
вызов:
pValue  := PyFunction.CallFuncByName('OnPaint',nil);

А тем не менее ошибка появляется...

Причем вызов из процедуры в которой создается экземпляр класса не дает ошибок. Только пи вызове из любого места появляется такая вот ошибка :(

Вот почему так понять не могу...


alex_***   (2005-11-23 09:28:00) [20]

и ты предлагаешь скачать это себе и заняться отладкой?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо