2012-03-19 22 views
5

Estoy usando python4delphi. ¿Cómo puedo devolver un objeto de una función de clase Delphi envuelta?Python4Delphi: Devolver un objeto python en una función. (DelphiWrapper)

Fragmento de código:

Tengo una sencilla clase de Delphi que envolvía al script Python, ¿verdad?

TSimple = Class 
Private 
    function getvar1:string; 
Public  
Published 
    property var1:string read getVar1; 
    function getObj:TSimple; 
end; 
... 
function TSimple.getVar1:string; 
begin 
    result:='hello'; 
end; 
function TSimple.getObj:TSimple; 
begin 
    result:=self; 
end; 

Hice el TPySimple como el demo32 para dar acceso de clase al código de Python. El nombre de mi módulo Python es prueba.

TPySimple = class(TPyDelphiPersistent) 
    // Constructors & Destructors 
    constructor Create(APythonType : TPythonType); override; 
    constructor CreateWith(PythonType : TPythonType; args : PPyObject); override; 
    // Basic services 
    function Repr : PPyObject; override; 

    class function DelphiObjectClass : TClass; override; 
end; 
... 

{ TPySimple } 

constructor TPySimple.Create(APythonType: TPythonType); 
begin 
    inherited; 
    // we need to set DelphiObject property 
    DelphiObject := TSimple.Create; 
    with TSimple(DelphiObject) do begin 
    end; 
    Owned := True; // We own the objects we create 
end; 

constructor TPySimple.CreateWith(PythonType: TPythonType; args: PPyObject); 
begin 
    inherited; 
    with GetPythonEngine, DelphiObject as TSimple do 
    begin 
     if PyArg_ParseTuple(args, ':CreateSimple') = 0 then 
     Exit; 
    end; 
end; 

class function TPySimple.DelphiObjectClass: TClass; 
begin 
    Result := TSimple; 
end; 

function TPySimple.Repr: PPyObject; 
begin 
    with GetPythonEngine, DelphiObject as TSimple do 
    Result := VariantAsPyObject(Format('',[])); 
    // or Result := PyString_FromString(PAnsiChar(Format('()',[]))); 
end; 

Y ahora el código Python:

import test 

a = test.Simple() 
# try access the property var1 and everything is right 
print a.var1 
# work's, but.. 
b = a.getObj(); 
# raise a exception that not find any attributes named getObj. 
# if the function returns a string for example, it's work. 
+4

Alguien votó sin decir por qué (una mala costumbre que algunas personas tienen, ¡me gustaría poder rechazarlas!) Aunque creo que deberías explicar más sobre lo que quieres decir (tal vez un fragmento de código) y lo que no funciona o lo que ya has intentado. –

+1

Esta pregunta me parece bastante vaga. La falta de actividad respalda ese sentimiento. –

+0

Muy bien muchachos, tomen algunos fragmentos de código. –

Respuesta

0

De acuerdo con la OP que ha encontrado la respuesta aquí: http://code.google.com/p/python4delphi/issues/detail?id=17

(A copiar y pegar para referencia)

Hola,

Tengo una sugerencia: exponer los objetos de Delphi a Python sin dolor utilizando el nueva característica RTTI (información del tipo de tiempo de ejecución) en D2010 (y más arriba).

Actualmente exponer una clase al código de Python alojado necesita que usted escriba demasiado código (consulte demo06), supongo que si aprovechamos la nueva característica de RTTI en las versiones más nuevas de Delphi, el proceso puede mejorarse mucho.

Por ejemplo, comprobar a cabo el proyecto integrado de Delphi cromo, todo lo que tiene que hacer para exponer la interfaz de cualquier clase de Delphi para el medio ambiente JavaScript, es registrar la clase:

// this is your class exposed to JS 
    Test = class 
    class procedure doit(const v: string); 
    end; 

initialization 
// Register your class 
    TCefRTTIExtension.Register('app', Test); 

// and in JavaScript code to call that class above: 
app.doit(''foo'')', '', 0); 

fresco! ¿No es así?

El código anterior se extrajo de: http://groups.google.com/group/delphichromiumembedded/browse_thread/thread/1793e7ca66012f0c/8ab31a5ecdb6bf48?lnk=gst&q=JavaScript+return+#

Algunos Introducción sobre RTTI introducido desde D2010: http://robstechcorner.blogspot.com/2009/09/delphi-2010-rtti-basics.html

0

se han topado con el mismo problema durante el uso de DelphiWrapper.

En primer lugar, permitir el uso de RTTI {ON} $ MethodInfo impedirá excepción:

provocará una excepción que no se encuentra ningún atributos denominados getObj.

Comentario clase TSimple así:

{$METHODINFO ON} 
TSimple = Class 
Private 
    function getvar1:string; 
Public  
Published 
    property var1:string read getVar1; 
    function getObj:TSimple; 
end; 
{$METHODINFO OFF} 

función Ahora getObj devuelve un valor - Un entero !!

Les mostraré lo que hice. He modificado Demo32:

Unit1.pas: Código

TPoint = class(TPersistent) 
private 
    fx, fy : Integer; 
    fName : String; 
public 
    constructor Create(); 
    procedure OffsetBy(dx, dy : integer); 
    function MySelf: TPoint; //**access self using function** 
published 
    property x : integer read fx write fx; 
    property y : integer read fy write fy; 
    property Name : string read fName write fName; 
    property MySelf2: TPoint read MySelf; //**access self using property** 
end; 

Python en Memo1.Líneas:

import spam 

p = spam.Point(2, 5) 

b = p.MySelf() //**using function** 
print 'Using MySelf: ', type(b), b 
c = p.MySelf2 //**using property** 
print 'Using MySelf2: ', type(c), c 

A continuación se da un resultado como este:

Using MySelf: <type 'int'> 31957664 
Using MySelf2: <type 'Point'> (2, 5) 

La función devuelve un int, eso es por cable. Tal vez es un puntero a un objeto TPoint incorrectamente envuelto por DelphiWrapper.

Finalmente encontré una forma de compromiso en Demo8 usando "AddMethod". ¡No es bello en absoluto! Pero funciona.

Cuestiones relacionadas