¡Dar Una Buena Imagen! Parte 2 - Delphi Básico
¡Dar Una Buena Imagen! Parte 2 - Delphi Básico
¡Dar Una Buena Imagen! Parte 2 - Delphi Básico
Delphi Bsico
DELPHISPANO
FB DELPHI SOLIDARIO
MAPA
LEGAL
Buscar
Search this website
Categoras
Elegir categora
Si os parece bien, recapitulamos: Comentaba al finalizar la entrada anterior, Dar una buena imagen! Parte 1, que estbamos en condiciones de proseguir, toda vez que habamos generado una base de datos y almacenado algunas imgenes en ella, que era uno de los requisitos que poda demandar el hecho de habernos planteado devolver una imagen a travs de nuestro servidor de DataSnap. No es que realmente nos hiciera falta explcitamente contar con una base de datos, pero recordando lo compartido en aquellas lineas, me pareca un poco mas didctico a efectos
delphibasico.com/delphi/?p=3918
A cerca de m
Salvador Jover
Proyecto DelpHispano
1/33
16/05/13
del blog y de las reflexiones que motivara su contenido. Por otro lado, hacer el cambio, y sustituir este origen por el de un fichero grfico, era sencillo y bastaba cambiar un par de lineas. As pues, y resumiendo, tomamos la decisin de guardar la imagen en la base de datos en un campo cuyo tipo de dato es adecuado a su contenido, habitualmente binario, en lugar de conservar la ruta donde ste est ubicado, y creamos una pequea utilidad para alimentar y gestionar la tabla de imgenes.
Redes Sociales
PROMOCIN XE4!
Solidario
S parte del grupo de facebook ms activo de nuestra Comunidad Hispana: Delphi Solidario. Unete a nuestro esfuerzo por hacer de la
2/33
16/05/13
Sin embargo, si nos referimos en concreto a la informacin sobre el uso de parmetros de tipo TStream, Jim Tierney dej escritos varios artculos imprescindibles, en los que se aborda el tema con bastante detalle. Uno de estos enlaces es DataSnap Server Method Stream Parameters, cuya lectura es necesaria, as como revisar el cdigo fuente que enlaza desde http://cc.embarcadero.com/item/26854. En la parte tercera de esta serie de artculos, al final de la misma, intentar recopilar todos los enlaces que me sea posible encontrar y que os puedan ser necesarios e interesantes. De hecho, durante los dos aos anteriores y este, se incrementa la documentacin tcnica con la aportacin de algunos artculos de compaeros de nuestra comunidad, que han ido introduciendo en la red las distintas reas de conocimiento de datasnap, aportando su granito de arena. Por supuesto, gran parte de esa posible lista sern recursos de habla inglesa.
blog.marcocantu.com marco's tech world Delphi Insider RSS de las Felix ColibriDelphi Source Code, Technical Articles, Delphi Trainings, Delphi Consulting and Development Nick Hodges Sip from the Firehose The Hackers Corner | Complex problems have simple easy-tounderstand wrong answers nete a 1 RSS de los comentarios WordPress.org entradas
Meta
Acceder
delphibasico.com/delphi/?p=3918
3/33
16/05/13
Subscribir
Comunidad Hispana
Permitid me que deje algunas ideas en el aire, aun a costa de simplificar. Dejado aparte todas aquellas clases que colaboran en la parte digamos propia de la estructura del servicio (las que crean propiamente el servicio como tal, fijan y configuran los distintos canales, abriendo o cerrando comunicaciones, etc.), quizs la primera consideracin que se me ocurre para ayudaros en esa primera toma de contacto, es resaltar que solo van a poder exponer mtodos remotos las clases descendientes TDataModule y TDSServerModule, as como cualquier descendiente de TPersistent, pero esta ultima opcin requerira de vuestra parte un esfuerzo adicional ya que os obligara a implementar las capacidades de desde servicio que ya vienen o introducidas TDataModule
/*Prog*/ Delphi-Neftal /*finProg*/ Andreano Lanusse Making Things Happen Aprendiendo Firemonkey Blog de Carlos G Daniel Luyo Daniel Magin Delphi en Movimiento Delphi Live Delphi Magic Delphi y FastReport
Comentarios recientes
Jose E Leyva en Dieciocho aos de Delphi y un largo camino por andar Salvador en Dar una buena imagen! Parte 2 GustavoSV en Dar una buena imagen! Parte 2 Al Gonzlez en Dieciocho aos de Delphi y un largo camino por andar Eliseo Gonzalez Nieto en Dieciocho aos de Delphi y un largo camino por andar
TDSServerModule. No parece lo mas habitual, por lo que, a efectos prcticos, consideraremos que vuestra atencin se va a centrar realmente en estas dos clases, que son las que usareis en vuestro da a da. La segunda idea es que un TDSServerModule es un descendiente de la clase TDataModule y por lo tanto, extiende la clase y la funcionalidad de sta. Bsicamente la diferencia que os guiar en la necesidad de hacer uso de una u otra ser, que vuestro modulo de datos en el servidor deba exportar datasets hacia el cliente. En ese caso, para que sean visibles estos datasets y podais conectarlos a travs del driver de datasnap, el contendor ser la clase TDSServerModule.
delphibasico.com/delphi/?p=3918
El blog de cadetill El blog de jachguate El Blog de Jhonny Surez El blog del Poli Glenn
4/33
16/05/13
COMUNIDAD
Recursos en la Red Publicaciones Truco o trato Foros
{ $ M e t h o d I n f oO N } T D S S e r v e r M o d u l e=c l a s s ( T D S S e r v e r M o d u l e B a s e ) e n d ; { $ M e t h o d I n f oO F F }
Legin Delphi Luis Felipe Gonzlez Torres Embarcadero MVP Puro Cdigo Blog de Jos Castillo Rescatando a Delphi Software: de Mexico para el mundo Waooo Delphi!
Esto enlaza con algo que nos comentaba desde la lectura de la ayuda en linea, cuando se nos dice que es necesario aplicar la directiva {$MethodInfo} para que los mtodos sean visibles desde la clase TDataModule. Esta directiva, {$MethodInfo on/off} trabaja conjuntamente con la que ayuda a nuestro compilador a generar informacin RTTI (Run Time Type Library) de clase, {$TYPEINFO ON/OFF}, haciendo necesario que ambas estn activas en el estado de la clase. De hecho, cuando nos dicen que los descendientes de TPersistent van a poder exponer mtodos remotos es porque esta clase TPersistent- activa la informacin de tipos y por lo tanto es una posible candidata en el nivel mas elevado de esa jerarqua, cuyos descendientes van a heredar tambin dicho estado. La directiva {$TYPEINFO} es equivalente a {$M+}. Podemos entender el papel de la RTTI, si
Stackoverflow en espaol
Embarcadero
Uso del componente TListView en nuestras aplicaciones mviles mayo 16, 2013 Jos Prez Le Dev du Jeudi Episode 11 mayo 16, 2013 tlaborde Ven a verme en Ciudad de Mxico y Guadalajara mayo 16, 2013 Anders Ohlsson RAD Studio XE4 Whats
5/33
Embarcadero MVP
Adriano Santos Alan Fletcher Alan Glei Alexander Alexeev Alexander Bozhko Alister Christie Andrey Terekhov Bob Swart
consideramos que precisamente, la generacin de esta metadata adicional en el servidor, ayudar al sistema a descubrir los mtodos a travs de una cadena de texto literal enviada en el mensaje compartido entre la aplicacion cliente y la aplicacin servidor, cadena de texto que representa la clase y el mtodo a invocar por el servidor. Si repasamos, por ejemplo, las lineas generadas automticamente en la unidad proxy, que es una plantilla que se crea a peticin del usuario con la informacin de los mtodos que descubre el servidor en el contexto de la aplicacin cliente, para facilitarnos no tener que mantener esta tarea que
delphibasico.com/delphi/?p=3918
16/05/13
puede ser repetitiva y tediosa, la implementacin que recrea la invocacin del mtodo EchoString se presenta como sigue:
new in the IDE (X) Info.plist mayo 16, 2013 Jose Leon Getting TWebBrowser on iOS to zoom mayo 15, 2013 Anders Ohlsson Report do Delphi Tour Multi-Device: Porto Alegre mayo 15, 2013 Fernando Rizzato Delphi for iOS in Zagreb, Croatia mayo 15, 2013 Pawel Glowacki iOS app dev with Delphi XE4 and FireMonkey 3 is a quantum leap beyond XE2 mayo 14, 2013 David Intersimone Report do Delphi Tour Multi-Device: Florianpolis mayo 14, 2013 Fernando Rizzato RAD Studio XE4 Whats new in the IDE (IX) Misc
6/33
f u n c t i o nT S e r v e r M e t h o d s 1 C l i e n t . E c h o S t r i n g ( V a l u e :s t r i n g ) :s t r i n g ; b e g i n i fF E c h o S t r i n g C o m m a n d=n i lt h e n b e g i n F E c h o S t r i n g C o m m a n d: =F D B X C o n n e c t i o n . C r e a t e C o m m a n d ;
F E c h o S t r i n g C o m m a n d . C o m m a n d T y p e: =T D B X C o m m a n d T y p e s . D S S e r v e r M e t h o d ; F E c h o S t r i n g C o m m a n d . T e x t: =' T S e r v e r M e t h o d s 1 . E c h o S t r i n g ' ; F E c h o S t r i n g C o m m a n d . P r e p a r e ; e n d ; F E c h o S t r i n g C o m m a n d . E x e c u t e U p d a t e ; e n d ;
Cary Jensen
Daniel Wildt
He incluido en negrita la cadena que identifica el mtodo a invocar. Dicha cadena representa la clase que contiene el mtodo y su nombre. De no existir esa informacin adicional extra, asociada a la clase, no seriamos capaz de encontrar ni los actores ni las acciones. En agosto del 2007 compartimos una entrada en el blog que os puede ayudar a entender este punto: La Granja y en la que precisamente vemos como invocar un mtodo en la clase a travs de su nombre. Creo recordar que hacamos trotar graciosamente a la clase TCaballo, adems de otras tropelias como alimentarle o permitir que relinche. La RTTI se nos presenta a varios niveles: desde un nivel mnimo que hace que una instancia sea capaz de reconocerse en una clase, que podramos llamar autoconciencia , hasta un nivel ms extendido que permite a la clase describirse y reconocerse en toda la funcionalidad que el desarrollador de la misma autorice a conocer y describir. Las zonas publicadas (published) de la clase, forman parte de esas zonas que generan informacin extendida y metadata adicional que la RTTI ya recoga con la directiva {$M+}. Al activar la directiva
delphibasico.com/delphi/?p=3918
Gonzalez Felix Colibri Filip Lagrou Francois Piette Germn Estvez Ruiz Guinther Pauli Jim McKeeth Jose Castillo Juan Antonio Castillo Kelyn Pena Lachlan Gemmell Luciano Pimenta Luis Alfonso Rey
16/05/13
{$MethodInfo} ayudamos a que la zona publica de la clase genere tambin esa informacin extra de tipos que de otra forma no se generara. La tercera idea, en la que me gustara incidir es que una gran parte de los mtodos, se nos presentan ntimamente ligados a la informacin de tipos. Es decir, podemos encontrar la necesidad de ejecutar necesite un procedimiento lo remoto habitual que es no que parmetros pero
Luis Felipe Gonzlez T. Magnus Flysjo Marcelo Nogueira Marcelo Varela Marco Cantu Marco Santn Marcos Antonio Moreira Marcos P. Gomes Martin Strohal Mike Sutton Newton Gaucho Nick Hodges | A man's got to know his limitations Nirav Kaku
EDN Visual
Video: Using the iOS TWebBrowser Component in Delphi iOS_WebBrowser Code Snippet mayo 12, 2013 Video: Using IBLite in Delphi iOS Apps mayo 10, 2013 Video: iOS SendCancelNotifications in Delphi mayo 8, 2013 Video: Using iOS AudioRecPlay in Delphi to Record and Play Back Sounds mayo 6, 2013 Video: Using iOS Location Services in Delphi apps mayo 4, 2013 Video: Using the iOS DatePicker in Delphi applications
7/33
existan parmetros de entrada y un tipo de retorno, en el caso de las funciones. As que en este punto nos podemos hacer la pregunta que este compaero me hacia entre lineas: Que tipo de dato necesito declarar como retorno de mi funcin, para exportar la imagen? Y si necesito una fecha? Puedo retornar un tipo propio de la logica de mi aplicacin, como por ejemplo una instancia de la clase TCliente? La respuesta a estas preguntas, la encontramos en los enlaces que compartamos en las lineas superiores de la entrada. En el primero de ellos, encontramos lo que buscamos: No todos lo tipos son soportados como parmetros.
but not all the parameter types are supported. The supported types are: Boolean SmallInt Integer Int64 Single Double
Olaf Monien Pedro Bento Radek Cervinka Ray Konopka Ricardo Boaro Robert Love Salvador Jover Samuel David
delphibasico.com/delphi/?p=3918
16/05/13
with TCalendarEdit mayo 2, 2013 Get Set Up for Delphi XE4 iOS Development abril 30, 2013 Video: Build Your First Multi-Device Delphi App abril 28, 2013 Building a C++ multi-tier master/detail Customer and Sales database application abril 26, 2013 Using the
TJSONValue and all descendents TDBXWideStringValue TDBXAnsiStringValue TDBXUInt8Value TDBXInt8Value TDBXInt16Value TDBXInt32Value TDBXInt64Value TDBXSingleValue TDBXDoubleValue
Foros Hispanos
Club Delphi
Comunidad Delphiaccess
Boost C++11 Algorithms Library with the C++Builder 64-bit compiler abril 26, 2013
Danysoft
delphibasico.com/delphi/?p=3918
8/33
16/05/13
Basic
TDBXStreamValue Both procedure and functions are supported, as well as out and var parameters.
En la entrada de Jim Tierney los encontris clasificados y agrupados de una forma mas clara, incluyendo algunos que no se mencionan explicitamente en la lista. Basic DBXValue TDBXAnsiStringValue TDBXAnsiCharsValue TDBXBcdValue TDBXBooleanValue TDBXDateValue TDBXDoubleValue TDBXInt16Value TDBXInt32Value TDBXInt64Value TDBXSingleValue TDBXStringValue TDBXTimeStampValue TDBXTimeValue TDBXWideCharsValue TDBXWideStringValue Collection
Estadisticas
Inicio: 08/03/2012
Connection
AnsiString Boolean Currency TDateTime TDBXDate TDBXTime Double Int64 Integer LongInt OleVariant Single SmallInt WideString
TDBXReader TParams
Estadsticas anteriores
TDBXConnection
TDataSet Delphi Bsico . 2003-2013 Connection DBXValue La fe no es la simple aceptacin TStream de unas verdades abstractas, TDBXConnectionValue sino una relacin ntima con
Cristo que nos lleva a abrir
Collection DBXValue nuestro corazn a este misterio TDBXReaderValue que se saben amadas por Dios. TDBXStreamValue
Benedicto XVI de amor y a vivir como personas
Por lo tanto, ahora s estamos en posicin de responder a las preguntas que nos formulbamos. No existe un parmetro que identifique directamente a una instancia de TImage o de la clase TBitmap. Sin embargo, genricamente nos podemos apoyar en el uso de una clase como TStream que permite manipular esta informacin como una secuencia de bytes, optando por cualquiera de los descendientes
delphibasico.com/delphi/?p=3918 9/33
16/05/13
que veamos apropiado para el contenido real. Tambin ahora estamos en condiciones de entender porque en el ejemplo del Restaurante, Luis Alfonso Rey se puede apoyar en la clase TDataSet como retorno de una de las funciones que su servidor exportaba. Recordad que el cdigo fuente de esta demo que sirvi en la exposicin durante las ultimas presentaciones del partner espaol se encuentra a vuestra disposicin en el link de la entrada inmediatamente anterior a esta.
16/05/13
nos va a permitir configurar el servidor. He seleccionado la opcin VCL Forms Application ya que no va a ser un servicio integrado en el sistema ni un proyecto de tipo consola sino que ser una aplicacin monda y lironda.
La siguiente parada ser para determinar como va a ser el servidor. Nuestro wizard necesita conocer como va a ser ese servidor, que capa de transporte de datos va a usar, si existirn filtros, si es una comunicacin segura y si adems, deseamos que incluya los mtodos de ejemplo que se aaden de ayuda. En el caso del servidor bsico se incluyen los mtodos EchoString y ReverseString, por defecto pero para servidores de tipo Rest, el sistema incluye adicionalmente un test en formato html capaz de evaluar los mtodos que exporta el incluyendo los administrativos. servidor,
delphibasico.com/delphi/?p=3918
11/33
16/05/13
En el siguiente paso, vamos a poder hacer un test al puerto 211, que es el que por defecto asigna DataSnap.
Y finalmente, seleccionamos de que clase heredar la creada por nosotros para albergar los distintos mtodos que exportar el servidor. Yo he elegido TDSServerModule ya que, en este caso concreto, s voy a incluir al menos un dataset. Existir un componente TSQLQuery que he llamado Imagenes_Interbase con el fin de que se pueda recorrer el contenido de la tabla.
delphibasico.com/delphi/?p=3918
12/33
16/05/13
Al finalizar el wizard, se habr creado el proyecto en el que existirn varias unidades, que representan respectivamente el formulario de la aplicacin, el mdulo que contiene los componentes que generan y configuran la estructura del servicio y un modulo adicional que el sistema por defecto denomina ServerMethodsUnit1, conteniendo la clase que va a exponer los servicios. publicados los que mencionbamos. Dejadme que escriba unas lineas de cdigo. Dad le un vistazo al formulario, tal y como queda tras aadir los componentes y comentamos. En dicho modulo estn de ejemplo mtodos
delphibasico.com/delphi/?p=3918
13/33
16/05/13
Nuestro TDSserverModule, es muy sencillo y contiene un query para recorrer la tabla y que sea el usuario desde la aplicacin cliente quien pueda seleccionar cual de las imgenes quiere que sea devuelta por el mtodo remoto, y un segundo query que efectivamente la devolver mediante el mtodo adecuado, apoyndose en el indice de esa imagen como parmetro de la que identifica entrada. Para ello, de que parametrizamos clave primaria consulta la imagen
S e l e c tB a n n e r f r o mB a n n e r s w h e r eI D B a n n e r=: I D B a n n e r
u n i tS e r v e r M e t h o d s U n i t 1 ; i n t e r f a c e u s e sS y s t e m . S y s U t i l s ,S y s t e m . C l a s s e s ,D a t a s n a p . D S S e r v e r ,D a t a s n a p . D S A u t h , D a t a . D B X M S S Q L ,D a t a . F M T B c d ,D a t a . D B ,D a t a . S q l E x p r ,D a t a s n a p . P r o v i d e r ,D a t a . D B X J S O N , D a t a . D B X I n t e r B a s e ,V c l . D i a l o g s ; t y p e T S e r v e r M e t h o d s 1=c l a s s ( T D S S e r v e r M o d u l e )
delphibasico.com/delphi/?p=3918 14/33
16/05/13
d e m o s _ i n t e r b a s e :T S Q L C o n n e c t i o n ; I m a g e n e s _ I n t e r b a s e :T S Q L Q u e r y ; d s p I m a g e n e s _ I n t e r b a s e :T D a t a S e t P r o v i d e r ; I m a g e n e s _ I n t e r b a s e I D B A N N E R :T I n t e g e r F i e l d ; I m a g e n e s _ I n t e r b a s e B A N N E R :T B l o b F i e l d ; G e t I m a g e B a n n e r _ I n t e r b a s e :T S Q L Q u e r y ; d s p G e t I m a g e B a n n e r _ I n t e r b a s e :T D a t a S e t P r o v i d e r ; G e t I m a g e B a n n e r _ I n t e r b a s e B A N N E R :T B l o b F i e l d ; p r o c e d u r ed e m o s _ i n t e r b a s e B e f o r e C o n n e c t ( S e n d e r :T O b j e c t ) ; p r i v a t e {P r i v a t ed e c l a r a t i o n s} p u b l i c {P u b l i cd e c l a r a t i o n s} f u n c t i o nE c h o S t r i n g ( V a l u e :s t r i n g ) :s t r i n g ; f u n c t i o nR e v e r s e S t r i n g ( V a l u e :s t r i n g ) :s t r i n g ; f u n c t i o nG e t I m a g e n B a n n e r A s J S O N ( A I D B a n n e r :I n t e g e r ) :T J S O N A r r a y ; f u n c t i o nG e t I m a g e n B a n n e r A s S t r e a m ( A I D B a n n e r :I n t e g e r ) :T S t r e a m ;o v e r l o a d ; e n d ; i m p l e m e n t a t i o n { $ R* . d f m } u s e sS y s t e m . S t r U t i l s ,U M a i n S e r v e r ,D a t a . D B X J S O N C o m m o n ;
f u n c t i o nG e t I m a g e n B a n n e r A s S t r e a m ( A S Q L Q u e r y :T S Q L Q u e r y ;A I D B a n n e r :I n t e g e r ) :T S t r e a m ;o v e r
16/05/13
b e g i n s t r e a m : =G e t I m a g e n B a n n e r A s S t r e a m ( A I D B a n n e r ) ; t r y R e s u l t : =T D B X J S O N T o o l s . S t r e a m T o J S O N ( s t r e a m ,0 ,s t r e a m . S i z e ) ; f i n a l l y s t r e a m . F r e e ; e n d ; e n d ; f u n c t i o nT S e r v e r M e t h o d s 1 . G e t I m a g e n B a n n e r A s S t r e a m ( A I D B a n n e r :I n t e g e r ) :T S t r e a m ; b e g i n R e s u l t : =G e t I m a g e n B a n n e r A s S t r e a m ( G e t I m a g e B a n n e r _ I n t e r b a s e ,A I D B a n n e r ) ; e n d ; p r o c e d u r eT S e r v e r M e t h o d s 1 . d e m o s _ i n t e r b a s e B e f o r e C o n n e c t ( S e n d e r :T O b j e c t ) ; b e g i n d e m o s _ i n t e r b a s e . P a r a m s . V a l u e s [ ' D a t a b a s e ' ]: =M a i n S e r v e r . G e t P a t h ; e n d ; f u n c t i o nT S e r v e r M e t h o d s 1 . E c h o S t r i n g ( V a l u e :s t r i n g ) :s t r i n g ; b e g i n R e s u l t: =V a l u e ; e n d ; f u n c t i o nT S e r v e r M e t h o d s 1 . R e v e r s e S t r i n g ( V a l u e :s t r i n g ) :s t r i n g ; b e g i n R e s u l t: =S y s t e m . S t r U t i l s . R e v e r s e S t r i n g ( V a l u e ) ; e n d ; e n d .
La pregunta mas interesante que yo me hara en vuestro caso, a la vista de la inspeccin ocular del cdigo, podra ser: Cuando escribimos una asignacin al valor de retorno de la funcin, como el que podemos ver en la linea inmediatamente inferior, qu sucede con la reserva de memoria que se ha hecho para gestionar el contenido del stream a devolver?
R e s u l t : =G e t I m a g e n B a n n e r A s S t r e a m ( G e t I m a g e B a n n e r _ I n t e r b a s e ,A I D B a n n e r ) ;
delphibasico.com/delphi/?p=3918
16/33
16/05/13
Fijmonos privada,
que
la
GetImagenBannerAsStream,
variable local de tipo TMemoryStream que va a ser instanciada cuando devolvemos un TStream, sin que por ningn lado se gestione que sta sea liberada. Sin embargo, al escribir la funcin que retornar esa misma imagen en el interior de una estructura del tipo TJSONArray, si que puedo liberar la memoria, ya que esa memoria asociada a la instancia del stream no forma parte del retorno sino que el mtodo de clase
T D B X J S O N T o o l s . S t r e a m T o J S O N ()
hace su propia reserva para la estructura TJSONArray y copia en ella el stream. Una de las cosas que aprend, al dar mis primeros pasos en el entorno, es que cada palo aguantaba su propia vela y que si en algn momento he gestionado la reserva de memoria por el motivo que sea, debo sin responsabilizarme de su liberacin. Eso sucede cuando instanciamos objetos, seres inferiores padre que les cobije. Tener un propietario, es una garanta que se responsabilizara de lo que suceda con esa criatura. Los componentes tienen esos privilegios as como sus descendientes. Gente con suerte! Sin embargo para un TStream o cualquiera de sus multiples caras, el sistema encuentra una solucin pactada. El parmetro InstanceOwner, de tipo boolean, media en el dilema abierto. un prrafo de la entrada de Jim Terney. Os leo
Accessing Values
The GetStream and SetStream methods have an InstanceOwner parameter. Passing True indicates that DBX owns the
delphibasico.com/delphi/?p=3918
17/33
16/05/13
stream and will free it. Passing False indicates that the caller owns the stream. To control how the generated proxy classes call SetStream and GetStream, there is an AInstanceOwner parameter on the proxy class constructor: Si a continuacin observamos con detenimiento los mtodos generados por el proxy para devolver el stream
La definicin del parmetro FInstanceOwner en GetStream( ) es la que establece como se va a liberar la memoria reservada previamente, de forma que no existan problemas derivados de su no liberacin. FInstanceOwner se estableca con un valor en el mismo constructor de la clase que va a exponer los mtodos
c o n s t r u c t o rT S e r v e r M e t h o d s 1 C l i e n t . C r e a t e ( A D B X C o n n e c t i o n :T D B X C o n n e c t i o n ;A I n s t a n c e O w n e r b e g i n i n h e r i t e dC r e a t e ( A D B X C o n n e c t i o n ,A I n s t a n c e O w n e r ) ; e n d ;
En este caso, tomaba el valor True (lo veris en el interior del evento onCreate del formulario cliente,
delphibasico.com/delphi/?p=3918 18/33
16/05/13
que usar el proxy). Es lgico que sea el cliente el que decida qu hacer con esa memoria y al asignar True lo que implica es que sea el propio sistema el que se encargue de liberar esa memoria y por lo tanto, no tendremos que hacer una llamada explicita para ello. Cuando no sea necesaria esa informacin, en una llamada posterior, el sistema podr decidir si libera la instancia antes de obtener un nueva invocacin.
que tambin es muy bsico y sencillo. El usario pulsar el boton Abrir DataSet y podr elegir una de las imagenes en el componente TImage inferior. Luego, al pulsar uno de los dos botones de la parte derecha, se ejecutara uno de los dos mtodos a los que alude.
delphibasico.com/delphi/?p=3918
19/33
16/05/13
u n i tU M a i n C l i e n t ; i n t e r f a c e u s e s S y s t e m . S y s U t i l s ,S y s t e m . T y p e s ,S y s t e m . U I T y p e s ,S y s t e m . R t t i ,S y s t e m . C l a s s e s , S y s t e m . V a r i a n t s ,F M X . T y p e s ,F M X . C o n t r o l s ,F M X . F o r m s ,F M X . D i a l o g s , D a t a . D B X D a t a S n a p ,I P P e e r C l i e n t ,D a t a . D B X C o m m o n ,D a t a . F M T B c d ,D a t a . D B , D a t a . S q l E x p r ,F M X . O b j e c t s ,D a t a . B i n d . E n g E x t ,F m x . B i n d . D B E n g E x t , S y s t e m . B i n d i n g s . O u t p u t s ,F m x . B i n d . E d i t o r s ,D a t a . B i n d . C o m p o n e n t s , D a t a . B i n d . D B S c o p e ,D a t a s n a p . D B C l i e n t ,D a t a s n a p . D S C o n n e c t ,F M X . L a y o u t s , F m x . B i n d . N a v i g a t o r ,U P r o x y ,F M X . L i s t B o x ; t y p e T F o r m 1=c l a s s ( T F o r m ) I m a g e 1 :T I m a g e ; D a t a S n a p C O N N E C T I O N :T S Q L C o n n e c t i o n ; B a n n e r s :T C l i e n t D a t a S e t ; D S P r o v i d e r C o n n e c t i o n 1 :T D S P r o v i d e r C o n n e c t i o n ; B a n n e r s B a n n e r :T B l o b F i e l d ; B i n d S o u r c e D B 1 :T B i n d S o u r c e D B ; B i n d i n g s L i s t 1 :T B i n d i n g s L i s t ; L i n k P r o p e r t y T o F i e l d 1 :T L i n k P r o p e r t y T o F i e l d ; B i n d N a v i g a t o r 1 :T B i n d N a v i g a t o r ; b t n D a t a s e t :T B u t t o n ; b t n M e t h o d J S O N :T B u t t o n ; I m a g e 2 :T I m a g e ; L a b e l 1 :T L a b e l ; B a n n e r s I D B a n n e r :T I n t e g e r F i e l d ; L i n k P r o p e r t y T o F i e l d 2 :T L i n k P r o p e r t y T o F i e l d ; c b x S e l e c t o r :T C o m b o B o x ; I n t e r b a s e :T L i s t B o x I t e m ; b t n M e t h o d S t r e a m :T B u t t o n ; P a n e l 1 :T P a n e l ; l a b B a s e D e D a t o s :T L a b e l ; p r o c e d u r eb t n D a t a s e t C l i c k ( S e n d e r :T O b j e c t ) ; p r o c e d u r eb t n M e t h o d J S O N C l i c k ( S e n d e r :T O b j e c t ) ; p r o c e d u r eF o r m C r e a t e ( S e n d e r :T O b j e c t ) ; p r o c e d u r eF o r m D e s t r o y ( S e n d e r :T O b j e c t ) ; p r o c e d u r ec b x S e l e c t o r C h a n g e ( S e n d e r :T O b j e c t ) ; p r o c e d u r eb t n M e t h o d S t r e a m C l i c k ( S e n d e r :T O b j e c t ) ; p r i v a t e {P r i v a t ed e c l a r a t i o n s} F I n s t a n c e O w n e r:B o o l e a n ; F S e r v e r M e t h o d s 1 C l i e n t :T S e r v e r M e t h o d s 1 C l i e n t ; f u n c t i o nG e t S e r v e r M e t h o d s 1 C l i e n t :T S e r v e r M e t h o d s 1 C l i e n t ; p u b l i c {P u b l i cd e c l a r a t i o n s}
delphibasico.com/delphi/?p=3918 20/33
16/05/13
f S t r e a m . L o a d F r o m S t r e a m ( T D B X J S O N T o o l s . J S O N T o S t r e a m ( G e t S e r v e r M e t h o d s 1 C l i e n t . G e t I m a g e
16/05/13
F S e r v e r M e t h o d s 1 C l i e n t : =T S e r v e r M e t h o d s 1 C l i e n t . C r e a t e ( D a t a S n a p C O N N E C T I O N . D B X C o n n e c t i o n ,F I
Y aqu tenis algunas capturas de la aplicacin en ejecucin, con una animacin mostrando el resultado.
delphibasico.com/delphi/?p=3918
22/33
16/05/13
16/05/13
ejecutandose
G e t S e r v e r M e t h o d s 1 C l i e n t . G e t I m a g e n B a n n e r A s S t r e a m ( i )
donde emerge el error que mostraba la animacin: Out of memory while expanding memory stream. TJSON array funcionaba correctamente en cualquier caso. As que os podis imaginar que parte de tiempo de demora de todas estas lineas ha era as estado en e intentar asegurarme que realmente propio cdigo. Yo creo que nosotros, como MVPs, o como personas comprometidas con la Comunidad, no podemos ocultar que exista un error puesto que no sera moral ni actuaria en conciencia. Mas al contrario, requiere de nosotros la responsabilidad de que perdamos un poco de nuestro tiempo intentando averiguar que lo produce, si es que realmente al final es producido por
delphibasico.com/delphi/?p=3918 24/33
16/05/13
alguna linea de la librera y no de nuestro desarrollo. Creo que es un buen signo de salud de la Comunidad y por ello, he aadido unas lineas para intentar capturar la naturaleza del problema y con mi psimo ingls, intentar subirlo a QC para que se pueda solucionar. Quizs ya est documentado. Quizs sea una Ni regresin idea. Es fruto algo de cambios ver en posteriores. que
los prximos das. Podis descargar el cdigo fuente demo_parte2 y si deseis seguir la lectura, voy a incluir algo de cdigo para analizarlo.
u n i tS e r v e r M e t h o d s U n i t 1 ; i n t e r f a c e u s e sS y s t e m . S y s U t i l s ,S y s t e m . C l a s s e s ,D a t a s n a p . D S S e r v e r ,D a t a s n a p . D S A u t h ; t y p e T S e r v e r M e t h o d s 1=c l a s s ( T D S S e r v e r M o d u l e ) p r i v a t e
delphibasico.com/delphi/?p=3918 25/33
16/05/13
El formulario cliente consta de un par de botones y una casilla de texto que nos permite probar con distintos tamaos. Tambin generamos un log del resultado, devuelto en las lneas del componente TMemo.
delphibasico.com/delphi/?p=3918
26/33
16/05/13
u n i tU M a i n C l i e n t _ f m x ; i n t e r f a c e u s e s S y s t e m . S y s U t i l s ,S y s t e m . T y p e s ,S y s t e m . U I T y p e s ,S y s t e m . R t t i ,S y s t e m . C l a s s e s , S y s t e m . V a r i a n t s ,F M X . T y p e s ,F M X . C o n t r o l s ,F M X . F o r m s ,F M X . D i a l o g s , D a t a . D B X D a t a S n a p ,I P P e e r C l i e n t ,D a t a . D B X C o m m o n ,F M X . O b j e c t s ,D a t a . D B , D a t a . S q l E x p r ,U P r o x y ,F M X . L a y o u t s ,F M X . M e m o ,F M X . E d i t ; t y p e T M a i n C l i e n t e F M X=c l a s s ( T F o r m ) b t n I m g 1 :T B u t t o n ; b t n I m g 2 :T B u t t o n ; D a t a S n a p C O N N E C T I O N :T S Q L C o n n e c t i o n ; I m a g e 1 :T I m a g e ; b t n T e s t :T B u t t o n ; M e m o 1 :T M e m o ; b t n C a n c e l :T B u t t o n ; n u m b o x :T E d i t ; p r o c e d u r eF o r m C r e a t e ( S e n d e r :T O b j e c t ) ; p r o c e d u r eF o r m D e s t r o y ( S e n d e r :T O b j e c t ) ; p r o c e d u r eb t n T e s t C l i c k ( S e n d e r :T O b j e c t ) ; p r o c e d u r eb t n C a n c e l C l i c k ( S e n d e r :T O b j e c t ) ; p r i v a t e {P r i v a t ed e c l a r a t i o n s} F F i n :B o o l e a n ;
delphibasico.com/delphi/?p=3918 27/33
16/05/13
16/05/13
R e s u l t : =F F i n ; e n d ; p r o c e d u r eT M a i n C l i e n t e F M X . F o r m C r e a t e ( S e n d e r :T O b j e c t ) ; b e g i n F I n s t a n c e O w n e r: =T r u e ; e n d ; p r o c e d u r eT M a i n C l i e n t e F M X . F o r m D e s t r o y ( S e n d e r :T O b j e c t ) ; b e g i n F S e r v e r M e t h o d s 1 C l i e n t . F r e e ; F S e r v e r M e t h o d s 1 C l i e n t : =N i l ; e n d ; f u n c t i o nT M a i n C l i e n t e F M X . G e t S e r v e r M e t h o d s 1 C l i e n t :T S e r v e r M e t h o d s 1 C l i e n t ; b e g i n i fF S e r v e r M e t h o d s 1 C l i e n t=n i lt h e n R e s u l t: =F S e r v e r M e t h o d s 1 C l i e n t ; e n d ; e n d .
F S e r v e r M e t h o d s 1 C l i e n t : =T S e r v e r M e t h o d s 1 C l i e n t . C r e a t e ( D a t a S n a p C O N N E C T I O N . D B X C o n n e c t i o n ,F I
Y finalmente, podis ver una imagen de la aplicacin en ejecucin, as como una animacin
delphibasico.com/delphi/?p=3918
29/33
16/05/13
16/05/13
diferencia
de
este
que
ahora
yo
he
expuesto. Quizs sea simplemente un error mio y me alegrara que fuera as. Espero que haya sido didctica esta segunda parte y que os pueda servir de algo todos estos comentarios. Hasta esa tercera parte que en teora cerrara la serie. Un saludo a todos.
Tw ittear
Like
Send
Comprtelo:
Twitter 1
Google +1
Correo electrnico Ms
datasnap
Delphi
qc
XE3
Salvador muy didctica tu explicacin, tienes vena de maestro ! Es un ejemplo muy prctico e interesante, hay algo que no
delphibasico.com/delphi/?p=3918 31/33
16/05/13
entiendo y es el por qu la redefinicin del mtodo GetImagenBannerAsStream tanto en la seccin private como public ? Son esas cosas de la OOP que no he podido masticar bien
Responder
Salvador dice:
marzo 26, 2013 a las 9:07 pm
Hola Gustavo, me alegra que te haya gustado. +1 Respecto al metodo, queda en la parte privada porque no quera que el servidor lo expusiera a la clase cliente. El compilador es capaz de distinguir por los parmetros que recibe cuando debe invocar a uno u otro. Pero ciertamente, si hubieras cambiado la firma del mtodo privado no hubiera cambiado el resultado.As queda mas misterioso jajaja
Inicialmente, exista en el ejemplo 2 bases de datos (sqlserver e internase) y con el selector podas cambiar de una base a otra ejecutando el mtodo. Luego, a medida que avanzaba en la escritura de la entrada, fui cambiando el cdigo para simplificarlo y que no quedara muy lioso, limpindolo, pero algunos detalles quedaron y ya no los rectifique. Un ejemplo de eso es el combobox, que no tiene demasiado sentido pero realmente tampoco afecta, ni para mal ni para bien. Un saludo, Salvador Responder
Deja un comentario
Tu direccin de correo electrnico no ser publicada. Los campos necesarios estn marcados *
delphibasico.com/delphi/?p=3918 32/33
16/05/13
Nombre
* *
Correo
electrnico Web
cinco + 1 =
Comentario
Puedes usar las siguientes etiquetas y atributos HTML: < a h r e f = " "t i t l e = " " >< a b b rt i t l e = " " >< a c r o n y mt i t l e = " " > < b >< b l o c k q u o t ec i t e = " " >< c i t e >< c o d e >< d e l d a t e t i m e = " " >< e m >< i >< qc i t e = " " >< s t r i k e >< s t r o n g >
Publicar comentario
Recibir un email con los siguientes comentarios a esta entrada. Recibir un email con cada nuevo post.
delphibasico.com/delphi/?p=3918
33/33