Code Conversion Guide/es

From Free Pascal wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) português (pt) русский (ru) slovenčina (sk)

Guía de conversión de código

Esta página trata sobre cómo trasladar o convertir código existente en Delphi o Kylix para que trabaje con el compilador Free Pascal (FPC) y el IDE Lazarus. Aunque Lazarus y el Free Pascal Compiler tienen aspectos en común con Delphi y Kylix, no son clones. Hay numerosas diferencias en las llamadas a librerías y en las convenciones utilizadas... y en muchas otras áreas, FPC es más rico y puede ser más exigente sobre la corrección de la sintaxis. Por favor leéte Lazarus For Delphi Users una guí despcriptiva de muchas de las diferencias de funcionamiento.

El proposito de esta guía es documentar algunas diferencias específicas que son frecuentes encontrar en el proceso de conversión de código al traladar código existente desde Delphi a FPF/Lazarus.

Este documento se ha ubicado en la zona de 'wiki base de conocimientos' por lo que puede ser fácilmente ampliado por cualquiera que se haya tropezado con un problema singular y quiera poner su experiencia en común con otras personas.

Seleccionar un componente o librería para convertir

Dónde encontrar código para convertir

Existe una gran cantidad de código disponible en la red que puede ser convertido para el uso con FPC y Lazarus. Esta página Page Of Code Sites es sólo un comienzo. Por favor, añada cualquier ubicación buena que conozca. TurboPower Software ha publicado recientemente la totalidad de su oferta comercial bajo la licencia MPL. Una lista de los paquetes disponibles se encuentra aquí.

Para evitar duplicar esfuerzos, los paquetes que ya han sido convertidos están listados en la página Components and Code examples. Si has convertido un paquete o estás trabajando en ello, haz una reseña en la página Current conversion projects.

Licencias

Las licencias del código existente varían desde libre/dominio público hasta versiones restrictivas que prohiben modificar, redistribuir y el uso comercial. Antes de convertir un un paquete, es conveniente examinar los téminos de su licencia y asegurarse de que es compatible con Lazarus y FPC. La selección de la licencia es especialmente importante con componentes, cuya mera ubicación en un formulario puede imponer una licencia no deseada o incompatible para toda la aplicación.

Cuando conviertas componentes, respeta los téminos del autor original y mantén todos los derechos de autor y los encabezados de licencia con sus direcciones de corrreo y url. Es cortés y a veces muy útil informar al autor de que sus componente va a ser convertido... especialmente si el componente está bajo una licencia restrictiva. Un interés renovado sobre un componente antiguo u olvidado a menudo incita al autor a revisar las restricciones de la licencia original.

En general, Dominio Público (software libre), y LGPL/MPL son las más flexibles para distribuir componentes. Para más información, Open Source Definition es un buen sitio para empezar. Asimismo hay varias comparaciones disponibles para ayudar a clarificar el impacto que los diversos tipos de licencias de obra pueden tener sobre el código que está relacionado con el mismo. Busca sobre los téminos "licencia de fuente abierta comparación"

Dependencias

Otro punto previo al comienzo del trabajo de conversión, es verificar que el código no tiene una profunda dependencia de otros paquetes que podrían no estar disponibles o representan un reto considerable de conversión. Algunos desarrollos de código libre son extensiones de paquetes propietarios/cerrados, que a menudo ya no están disponibles o lo están bajo licencias inapropiadas.

Acerca del compilador

Ver (aunque parece que no funcionan):

Acerca de Sistemas Operativos y Plataformas

Lazarus y el Compilador Libre de Pascal son herramientas multiplataforma y multiarquitectura de desarrollo cruzado, es decir lo escrito en una plataforma puede compilarse ¡y funcionar! en otra. Por contra mucho código Delphi existente ha sido diseñado específicamente para correr sobre la plataforma Intel+Win32. Si el componente candidato tiene mucho código específico win32, tal vez sea más conveniente buscar otra alternativa menos dependiente de la plataforma. Pero no te detengas por ello... ¡es verdaderamente sorprendente lo que el LCL soporta!

Conviertiendo

Configurando el entorno de Lazarus para un proyecto de conversión

Crear un proyecto de prueba

  • Poner el código a convertir en un subdirectorio (convertdir, por ejemplo)
  • Desde Lazarus crear un proyecto nuevo.
  • Guardar (Archivo->Guardar Todo) en el subdirectorio convertdir. Poner nombres significativos a este proyecto y a su unidad principal es optativo.
  • Abrir la unidad principal del proyecto a convertir.
  • Añadirla al proyecto: Proyecto->Añadir archivo del Editor al Proyecto
  • Utilice Herramientas->Chequeo Rápido de la sintaxis o bien Ejecutar->Construir todo para empezar.

Cuestiones iniciales a tener en cuenta

  • Las series 1.0.x del compilador distinguen en los nombres de fichero mayúsculas y minúsculas. Si se trabaja con esta versión, es conveniente poner todos los nombres en minúsculas. En caso contrario se producirá el error "Archivo no encontrado"

Código fuente Delphi VCL y Kylix CLX en Lazarus

Al convertir código fuente Delphi / Kylix, a menudo es útil mirar la declaración para comprobar lo que hace una función concreta. El IDE de Lazarus puede analizar el código Delphi / Kylix. Para ello es necesario configurar las opciones del compilador y las rutas de búqueda. Esto hace más fácilmente utilizando plantillas de proyecto: Entorno->Definir editor de CodeTools->Insertar plantilla.

Conversion problems and solutions

Delphi / Kylix file equivalents in Lazarus

Delphi / Kylix Description Lazarus Description
.pas

.dfm/.xfm,

.dcu/.dpu,

.dpr(main project file),

.res,

.dof/.kof

---

---

---

Delphi Source File,

Delphi Form,

Delphi Compiled Unit,

Delphi Project,

Windows Resource File,

Delphi Option File

.pas, .pp

.lfm,

.o,

.lpr

---

---

.lrs,

.lpi(main project file),

.ppu

Pascal unit file,

Form data file,

Compiled unit file,

Project file,

Resource file,

Project options file,

Lazarus resource file,

Lazarus project information file,

FPC unit description file


Así pués un archivo .dcu de Delphi contiene, más o menos, la información de los archivos .o y .ppu de FPC. Un .ppu es principalmente la cabecera (interfaz), y el .o la parte de la implementación. Las funciones "en línea" (inline) que residen en el .ppu, son la principal excepción a esta regla.

Convirtiendo proyectos/formularios/unidades de DElphi a Lazarus

Cambia el nombre o copia el archivo .dpr a un .lpr. Comenta o elimina la directiva

{$R *.res}

y añade la directiva

{$mode delphi}{$H+}

o bien esta otra

{$mode objfpc}{$H+}

en el .lpr. El IDE de Lazarus ayuda en esta cuestión en la opción del menú Herramientas "Convertir proyecto de DElphi a proyecto de Lazarus...". En ella se pide un .dpr (proyecto Delphi) y lo convierte en un .lpr; además, crea el archivo. lpi archivo y convierte todas las demás unidades.

Muchos formularios de Delphi se puden convertir para trabajar en Lazarus utilizando el asistente del IDE, que se encuentra en el menú Herramientas como tema "Convertir archivo DFM a LFM". Utilice el diálogo, seleccione el dfm y el convertidor hará el resto.

Si necesitas convertir una unidad (con o sin formulario), Lazarus incluye una opción "Convertir unidad de Delphi a unidada de Lazarus" que haá por tí lo siguiente:

  1. poner en minúsculas los nombre de archivo de inclusiones y de la sección uses.
  2. convierte el .dfm a .lfm (normalmente sin comprobar el contenido, únicamente el formato)
  3. crea un .lrs vacío (el contenido se creará después)
  4. añade la directiva
    {$mode delphi}
  5. sustituye la rferencia a la unidad windows por LCLIntf
  6. añade la unidad LResources si es preciso (si de usa .lrs
    uses LResources
    se pondrá en la sección de implementación)
  7. elimina las unidades variants
  8. elimina la directiva
    {$R *.dfm}
  9. crea la sección de inicialización y añade en ella la directiva
    {$i unit.lrs}

Esto permite una rápida y fácil conversión de la mayoría de las unidades de Delphi a Lazarus. No se realiza ninguna validación ni cambios automáticos de sintaxis, por lo que cualquier cambio en la sintaxis se hará manualmente, así como de unidades referenciadas, sustitución de algunos componentes,..., aunque hay asistentes de ayuda disponibles para facilitar esta tarea, especialmente en el caso de la reparación de formularios (.lfm)

Seleccionar el modo correcto de compilación

El compilador FPC soporta 5 modos diferentes de pascal. Por ejemplo, TP para turbo pascal, que permite compilar unidades turbo pascal. Está también el modo de compatibilidad DELPHI, cuya utilización permite una fácil conversión del código existente. El modo preferido en Lazarus es OBJFPC, muy parecido a DELPHI pero menos ambiguo en la sintaxis. Estos son puntos importantes:

El modo se puede seleccionar en la línea de ordenes o al principio del código fuente. Utillizar la línea de ordenes tien la ventaja de que no hay que cambiar el código fuente, pero la desventaja de que hay que documentarlo para los demás.

Muchas unidades DELPHI compilan con FPC añadiendo a las mismas

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}

inmediatamente a continuación del nombre de la unidad.

Para más detalles acerca de los modos de Free Pascal FPC ver Documentación de Free Pascal

Consideraciones sobre codificación para Multiplataforma

  • El código Ensamblador en línea (inline assembler) es problemático, dado que es específico para la arquitectura Intel. Muchos desarrolladores hacen el prototipo en Pascal y después utilizan su equivalente ensamblador optimizado. Por suerte TurboPower hizo esta operación dejando también el código Pascal. Si este es el caso del paquete que estás convirtiendo, repón el código pascal.
  • No hagas referencias a direcciones concretas de memoria, como el área de BIOS. Averigua lo que el código necesita y busca una alternativa portable entre plataformas.
  • No utilices trucos específicos de procesador (por ejemplo, Intel TSC) sin encerrar ese código en un selector (IFDEF) para esa plataforma... y provee una alternativa para entornos que no tienen esa máquina concreta.
  • Si es necesario código específico para un SO, haz uso de bloques selectores (IFDEF). Ver más abajo una lista de macros.

Variables, "defines" y macros útiles del compilador

Para escribir código que se adapte, y se comporte de forma distinta según el sistema, se utiliza la directiva

{$ifDef identificador}.
  • {$IfDef FPC}

Esta se define cuando se tuiliza el compilador FPC. Es útil para escribir código válido tanto para Delphi como para FPC. Por razones de compatibilidad en FPC se define la macro DELPHI en modo Delphi, por lo tanto no se puede usar {$IFNDEF DELPHI}.

  • {$IfDef LCL}

Esta se define para utiñizar el paquete LCL. Es útil para escribir código que funcione con LCL y Delphi.

  • {$IfDef LCLGtk}
    ,
    {$IfDef LCLWin32}
    ,
    {$IfDef LCLQt}
    , ...

Esta varible se define para utilizar el LCL en una determinada plataforma, usando los componentes visuales (widgetset).

  • {$IfDef Unix}
    ,
    {$IfDef Win32}
    , ...

Determina la utilización de FPC para un deteminado SO como destino. Delphi define "Linux", "Win32" y "MSWindows". Free Pascal funciona en muchas más plataformas y por tanto se recomienda utilizar especificaciones más generales. Por ejemplo "Unix" está definido para Linux, FreeBSD, NetBSD y OpenBSD, en los que Lazarus ya funciona. Para código que corra tanto en FPC cómo en Delphi utilice:

{$IfDef Linux}
  {$Define Unix}
{$EndIf}

para que funcione en Kilix.

  • {$IfDef ENDIAN_BIG}

Esta variable se definirá para procesadores como el powerpc (ordenadores Apple, hasta el MacOSX 10.2, por ejemplo) que tienen la disposisicón del byte invertida respecto de los procesadores compatibles intel.

  • {$IfDef ENDIAN_BIG}

Para más detalles ver Documentación de FPC.

Soporte para 32bit / 64 bit

Los punteros para 64bit requieren 8 octetos en vez de los 4 de 32bit. El tipo entero (integer) permanece de 32bit por compatibilidad. Esto supone que ya no es posible transformar enteros en punteros y viceversa mediante "typecast". FPC define dos nuevos tipos: PtrInt y PtrUInt. PtrInt es un entero con signo de 32bit en plataformas 32 bit y de 64 bit en plataformas 64bit. PtrUInt funciona igual, excepto que es un entero sin signo. Por tanto, para código que funcione tanto en FPC cómo en Delphi hay que escribir esto:

 {$IFNDEF FPC}
 type
   PtrInt = integer;
   PtrUInt = cardinal;
 {$ENDIF}

Sustituya todas las ocurrencias de integer(SomePointerOrObject) por PtrInt(SomePointerOrObject).

Para más información ver Guía de programación para multiples plataformas Multiplatform Programming Guide

Buscando un identificador perdido

La organización de la LCL y de la VCL son diferentes. Cuándo tenemos un error de compilación "no encontrado" sobre una clase o un identificador, lo más probable es que la definición de los mismos se encuentre en una unidad distinta de la esperada. Una completa referencia cruzada se puede encontrar buscando en lazarus/docs/xml o en el directorio lcl.

Por ejemplo, el común tbutton, dará error en Delphi, ya que se encuentra en una unidad llamada buttons.pp. El siguiente mandato encuentra la unidad correcta rápidamente (en el directorio fuente lazarus):

 grep -in ' tbutton =' lcl/*

(Nota del traductor: esta sintaxis de grep no da resultados en windows. Yo en windows utilizo el 'buscar' del SO en el ámbito del directorio en que está instalado lazarus, para archivos .pas o .pp que contienen referencias al término deseado. Incluso funciona, a veces, la utilidad del IDE de buscar la declaración)

Diferencias mayores entre las unidades de Lazarus y las de Delphi

¡Por favor, añada lo que sepa sobre este tema!

  • Windows -> Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)

Dado que la LCL no es específica de windows, el código para acceder la API win32 está condensada en interfaces separadas que son accedidas desde la unidad LCLIntf. Hay que tener en cuenta que Lazarus no intenta emular win32, por lo que muchas funciones no están incluidas y otras no funcionan exactamente como sus homólogas win32. Estas funciones existen únicamente para dar compatibilidad con Delphi y deben ser utilizadas únicamente para una migración rápida y "sucia". Las definiciones tipos están fragmentadas, por lo que es necesaria la unidad LCLType, y a veces también VCLGlobals. La unidad LCLProc también contiene algunas funciones que pueden ser útiles para manipulaciones a bajo nivel como "FreeThenNil" tal como se hace en Delphi 5 y superiores o "DeleteAmpersands" para eliminar los "&" sobrantes de una cadena de control (vs & & & etc). Hay que incluir la unidad Interfaces en la cláusula uses del archivo .lpr para iniciar adecuadamente el conjunto de controles apropiado (widgetset).

  • Messages -> LMessages

Los mensajes de control (TControl Messages) para los eventos de retrollamada de win32 en el formato WM_CALLBACK y sus estructuras asociadas se encuentran en la unidad Delphi Messages. En la LCL estos tipos de mensajes y sus estructuras están usualmente en LMessages, normalmente con un cambio en el nombre, de WM a LM, así, por ejemplo, WM_MOUSEENTER se transforma en LM_MOUSEENTER, y TWMMouse en TLMMouse.

  • Graphics, Controls -> GraphTypes, GraphMath, Graphics, Controls

Para simplificar las cosas y romper la complejidad de las referencias entre unidades, muchos tipos han sido abstraidos en una unidad común llamada GraphType, que incluye lo que en Deplhi se encuentra en las unidades Graphics o Controls. Así que tendrá que ser incluida. Otra unidad igualmente incompatible con Delphi es GraphMath, que añade el tipo TFloatPoint para precisión, rutinas para trabajar con curvas de Bézier, líneas y arcos, sobrecarga de algunos operadores para trabajar con TPoints y TRect, como, por ejemplo, punto1: = punto2 + punto3, y comparar dos Trect así if (rect1 = rect2) then ...such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...

  • Mask -> MaskEdit

Para racionalizar las convenciones sobre nombres, la unidad para la clase TMaskEdit se llama MaskEdit y no el confuso Mask de muchas versiones Delphi.

  • StdCtrls->StdCtrls,Buttons

En muchas versiones de Delphi TButton se encuentra en StdCtrls, mientras que TSpeedButton y TBitBtn están en Buttons. Por consistencia y simplicidad la LCL ubica todos los tipos de botones en la unidad Buttons, es por tanto una buena idea incluirla para evitar problemas de conversión.

Diferencias entre Delphi y FPC/LCL sobre propiedades y métodos

  • EL TBitmap de la LCL tiene una propiedad lienzo (canvas)
  • En la LCL las propiedades de las dimensiones de la ventana (TForm.ClientWidth/ClientHeight) y las proiedades de las dimensiones de su área cliente (TForm.Width/Height)tienen el mismo valor. Esto es así porque los valores de las dimensiones de la ventana no incluyen las dimensiones de su marco. Ver: Preguntas sobre Lazarus

Diferencias semánticas

Orden de evaluación de los parámetros
Delphi garantiza que los parámetros se evalúan siempre de izquierda a derecha. FPC no garantiza esto, y evaluará los parámetros en el orden que produzca un código más optimo.
Procedimientos y funciones anidadas como variables de procedimiento
Delphi pasa el puntero al marco (framepointer) del procedimiento padre siempre en la pila, y es quién llama el que debe quitarlo. Esto significa que no puede acceder a las variables del padre, y sin embargo puede pasar la dirección de una función anidada a otra función que podrá usarla como cualquier variable de procedimiento.
FPC, por otro lado pasa el puntero al marco del procedimiento padre cómo el primer parámetro oculto de acuerdo a las convenciones actuales de llamada, esto significa que si se llama a un procedimiento anidado como si fuese una variable de procedimiento ordinaria todos los parámetros pasados se moverán una posición.
En resumen, no llames a procedimientos anidados a través de variables de procedimiento.

Diferencias de sintaxis

¡Por favor, añada lo que sepa sobre este tema!
Debido al rigor inherente a FPC, algunos cambios en la sintaxis son necesarios, aunque con la directiva {$Mode Delphi} podemos relajarnos al estilo Delphi. No obstante lo cual, es recomendable cumplir con las reglas de sintaxis del modo {$Mode ObjFPC}, incluso cuando el código va a ser compartido entre Delphi y la LCL. Algunos son simples buenas prácticas de escritura de código, y otras porque el modo Delphi no es completamente exacto, o porque el código aceptable en Delphi no funciona como debe con FPC, incluso aunque compila. Para ello, aunque no todo es estrictamente necesario, los siguientes cambios deben considerarse obligatorios:
Al asignar una función de manejo de un evento, antepon un "@" a su nombre
Por ejemplo, se puede asignar la llamada a un botón manualmente
Delphi
OBJFPC
<delphi>
begin
  if not Assigned(MiBoton.OnClick) then 
    MiBoton.OnClick:= UnaFuncion;
    //@ no necesario
    //más código...
end;

</delphi>

<delphi>
begin
  if not Assigned(MiBoton.OnClick) then
     MiBoton.OnClick:= @UnaFuncion;
    //@ Es necesario
    //más código...
end;

</delphi>


Al llamar a una variable procedural usar esta sintaxis: ProcNombre()
En Delphi no existen diferencias entre el resultado de una función y una variable, en cambio en FPC, la llamada a una función debe llevar los paréntesis, incluso si no hay argumentos. Por ejemplo:
Delphi
OBJFPC
<delphi>
With (UnObjeto) do 
 begin
  If Assigned(OnMiLlamada) then
    OnMiLlamada;
    //paréntesis no necesarios
 end;

</delphi>

<delphi>
With (UnObjeto) do 
 begin
  If Assigned(OnMiLlamada) then
    OnMiLlamada();
    //los paréntesis son necesarios
 end;

</delphi>


Al obtener los valores de un puntero a registro hay que deshacer antes la referencia
En Delphi no es necesario deshacer la referencia a un puntero de registro para acceder a sus valores, se trata, de hecho, cómo si fuese un registro, o culaquier otro objeto. En FPC es necesario deshacer la referencia antes. Un ejemplo,
Delphi
OBJFPC
<delphi>
Function DameValores(UnRegistro: PMiRegistro):Integer;
 begin
  If Assigned(UnRegistro) then
    Result:=UnRegistro.UnValor
  else
    Result:=0;
 end;

</delphi>

<delphi>
Function DameValores(UnRegistro: PMiRegistro):Integer;
 begin
  If Assigned(UnRegistro) then
    Result:=UnRegistro^.UnValor
  else
    Result:=0;
 end;

</delphi>


Para acceder a caracteres de la cadena que es una propiedad de un objeto, esta debe ser encerrada entre paréntesis
Con Delphi las porpiedades de los objetos se tratan como cualquier otra constante o variable, incluso para acceder directamente a los caracteres individuales de una cadena, pero esto no es posible en FPC, específicamente para propiedades indexadas. PAra hacerlo hay que encerrar la propiedad etnre paréntesis, para diferenciar. Aunque no es necesario en todos los casos, es buena práctica hacerlo así siempre. Por ejemplo,
Delphi
OBJFPC
<delphi>

Type TUnComponente=class(TComponent)

 //Más código......

Published Property MiCadena:String index 3 read GetMiCadena;

 //Más código....

End;

var

 MiLetra:char;

begin

 If Length(MiCadena)>2 then
   //paréntesis no necesarios
   MiLetra:= MiCadena[3];
   //Más código......

end; </delphi>

<delphi>

Type TUnComponente=class(TComponent)

 //Más código...

Published Property MiCadena:String index 3 read GetMiCadena;

 //Más código...

End;

var

 MiLetra:char;

begin

 If Length(MiCadena)>2 then
   //paréntesis necesarios
   MiLetra:= (MiCadena)[3];
   //Más código......

end; </delphi>


Hay que convertir los punteros al tipo real que espera la función con que se utiliza
En Delphi se puede tener un puntero nulo representando a un objeto. Aunque puede parecer extraño, es corriente que se de especialmente en paquetes de muchos componentes, cómo forma de evitar referencias circulares entre objetos de unidades distintas. En Delphi es posible pasar el puntero nulo a una función que espera un objeto de ese tipo, sin realizar la conversión al tipo real, en FPC hay que realizar la conversión de forma explícita. Por ejemplo:
Delphi / ObjFPC

<delphi>

Unit Unidad1
 Type TUnObjeto=class(TComponent)
   //Más código...
 End;
Procedure HacerAlgo(Value: TSomeObject);
Function GetUnObjeto: TUnObjeto;
Unit Unidad2
 Type TUnComponente=class(TComponent)
  //Más código...
 Published UnObjeto: Pointer;
 //Más código...
 End;

</delphi>


Delphi
OBJFPC

   -- Aplicación ---------- <delphi>

var 
  MiComponente: TUnComponente;
begin
  MiComponente.UnObjeto:=GetUnObjeto
  //Más código...
  HacerAlgo(MiComponente.UnObjeto);
end;

</delphi>

   -- Aplicación ---------- <delphi>

var 
  MiComponente: TUnComponente;
begin
  MiComponente.UnObjeto:=Pointer(GetUnObjeto);
  //Más código...
  HacerAlgo(TUnObjeto(MiComponente.UnObjeto));
end;

</delphi>

Recursos

Los recursos (iconos, imágenes, cursores, etc.) Delphi son específicos de win32 y no son compatibles con Lazarus, hay que rehacerlos y compilarlos con la utilidad lazres, que se puede encontrar en el directorio dir_de_lazarus/tools. Deberás compilar tú mismo esta utilidad.
  • linux y *nix
  cd dir_de_lazarus/lazarus/tools
  make install
  • windows
    • Abrir una consola con CMD y escribir lo siguiente:
  cd dir_de_lazarus\tools
  dir_de_lazarus\fpc\2.2.0\bin\i386-win32\make install
(nota del traductor: esto en realidad construye todas las utilidades que hay en tools)
Para añadir rucursos a tu aplicación:
  • lazres mirecurso.lrs mi_dibujo.xpm otro_dibujo.xpm.
  • Añade la unidad LResources en ls cláusula Uses de la unidad.
  • Incluye la referencia al archivo .lrs creado dentro de bloque de iniciación.
Ejemplo:

<delphi>

Unit Unidad1
 function TForm1.LoadGlyph(const NombreGrafico: String): TBitMap;
  begin
    Result:= TPixmap.Create; //¿no debería ser Result:= TBitMap.Create;?
    Result.LoadFromLazarusResource(NombreGrafico);
  end;
//Más código...
begin
  BotonRapido.glyph:= LoadGlyph('mi_dibujo');
  //Más código...
end;
initialization
 {$I Unidad1.lrs}
 {$I mirecurso.lrs}
end.

</delphi>

Desde la versión 2.2 del FPC, incluso los ejecutables ELF de Linux admiten recursos binarios, por lo que lo que se pueden utilizar los típicos recursos .res que se utilizan en Delphi
Ejemplo:

<delphi>

//hasta aquí todo igual
initialization
 {$I Unidad1.lrs}
 {$R mirecurso.res}
end.

</delphi>

Otro método para convertir proyectos Delphi o Kylix a Lazarus

  • Rename or copy all .dfm or .xfm files to .lfm (Early Delphi versions do not produce a text-based .dfm file. The convert utility, if present in the \bin folder can be used to covert the .dfm first))
  • Rename or copy .dpr file to .lpr
  • Make necessary changes to .lpr file:
  1. Add {$mode delphi}{$H+} or {$mode objfpc}{H+} directives
  2. Add 'Interfaces' to uses clause
  3. Comment out or delete {$R *.res} or directive
  • Make necessary changes to all .pas unit files:
  1. Add {$mode delphi}{$H+} or {$mode objfpc}{H+} directives
  2. Add 'LResources', and if the form has buttons, add 'Buttons' to uses clause
  3. Comment out or delete {$R *.dfm} or {$R *.xfm} directive
  4. Add 'Initialization' section at the end of each unit file, and add {$I unitname.lrs} directive in it
  • Select Project->New Project from file
  • Select the .lpr file
  • At 'Create a new project' window, choose 'Application'
  • Build project and make further necessary corrections to get proper compilation, at this point the .lpi file is generated automaticaly. You may also get 'Error reading Form' messages, click on 'Continue Loading' if you do.
  • Save all, and you have a Lazarus project :-)

Getting Help

If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help.

Documentation

For pure Object Pascal and FPC issues The best place to start is the Free Pascal Documentation by Michaël Van Canneyt and Florian Klämpfl.
For more Lazarus oriented problems The Lazarus Project Documentation in the Lazarus-CCR Knowledgebase Main Page is the next place to look.

Peer support

Mailing lists You can post a question on any of the mailing lists for the Free Pascal Compiler or the FPC forums where a lot of experts are subscribed.
If you have access to IRC: On irc.freenode.net: #fpc for FPC, or #lazarus-ide for Lazarus

Knowledge bases

There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems:

  • Tamarack Associates operates a fast search engine specifically for the Borland usenet archives.
  • Mer Systems Inc. provides a similar search engine.
  • Another outstanding source of information along with a sitewide search capability is Earl F. Glynn's Computer Lab and Reference Library.

Packaging and Releasing your component

Creating a Lazarus package for your component(s)

Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of Lazarus Packages that should be read before beginning this process.

Documentation

The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.

Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the Sand Box practice area.

Creating a Code Release Page

The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.

The following procedure will let you create a Code Release Page with your browser:

  • Go to the Release new component
  • Type the name of your component in the textbox and click on Create Article
  • Fill in the template and hit save.
  • Edit the Components and Code examples page and add the link to your newly created page to the "Released Components" section. Save the modified page.

Submitting the component

If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators (Tom Lisjac or Vincent Snijders) and we'll add it to the repository. Before we upload it to SourceForge, you have to create a Code Release Page to describe your component. You can use the Release new component page, to start creating such a page.

If you think you need to continue to develop on the component, we can also put it into SVN so you'll continue to have access to it. If we get tired from submitting your patches, we will give you write access to the SVN, so you can commit your patches yourself. For details see Using the Lazarus-ccr SVN repository.

Contributors and Changes

This page has been converted from the epikwiki version.

  • Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 VlxAdmin
  • Moved Getting help from the main page. T. Lisjac - 9/24/2003 VlxAdmin
  • Added documentation templates, procedure and links. 9/25/2003 VlxAdmin
  • LCLLinux was renamed to LCLIntf, Jesus Reyes, 9/27/2003
  • added more information on Unit changes, AndrewJohnson 9/27/2003
  • Updated Syntax differences, including some examples, AndrewJohnson 9/27/2003
  • FPC 1.0.x doesn't support interfaces, Vincent Snijders 9/28/2003
  • Fixed some of the examples per new WikiWord definition, 9/28/2003 VlxAdmin
  • Made code more consistant to remove last accidental Pascal WikiWord definitions, AndrewJohnson 9/27/2003
  • Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, AndrewJohnson 10/17/2003
  • Use pascal stylesheet to make example code more readable, AndrewJohnson 10/18/2003
  • Added 'Another method to convert a Delphi or Kylix project to Lazarus' section , George Lober, 2/17/2006
  • Traducción al castellano (español) iskraelectrica (jldc) / mayo de 2008.