2011-01-31 5 views
7

Como regla general he eludido muchas trampas de diseño clásicas cuando uso punteros aprovechando los parámetros de Const (sin tipo) en lugar de los tipos de código fijo. Esto me da la ventaja de la velocidad al ejecutar funciones gráficas avanzadas al tiempo que dejo los detalles técnicos al compilador. También ha hecho que sea fácil usar el mismo código en Delphi y Free Pascal con cambios mínimos. Sin embargo, últimamente he empezado a cuestionar esto debido a las declaraciones vagas de Embarcadero sobre la evolución de Delphi y su futuro modelo de seguridad.¿Los parámetros de constricción y el encasillado funcionarán como antes en Delphi 64bit?

Por ejemplo, concider el siguiente ejemplo:

Type TSomeDataProc = procedure (const aInput;var aOutput) of Object; 

(* Convert 8-bit pixel to 16-bit pixel *) 
Procedure TMyClass.ProcessSomeData08x565(Const aInput;var aOutput); 
var r,g,b: Byte; 
Begin 
    FPalette.ExportTriplets(Byte(aInput),r,g,b); 
    Word(aOutput):=(R SHR 3) SHL 11 or (G SHR 2) SHL 5 or (B SHR 3); 
End; 

(* Convert 16-bit pixel to 24-bit pixel *) 
Procedure TMyClass.ProcessSomeData565x888(Const aInput;var aOutput); 
Begin 
    With TRGBTriple(aOutput) do 
    Begin 
    rgbtRed:=(((word(aInput) and $F800) shr 11) shl 3); 
    rgbtGreen:= (((word(aInput) and $07E0) shr 5) shl 2); 
    rgbtBlue:= ((word(aInput) and $001f) shl 3); 
    end; 
End; 

ahora tenemos dos procedimientos con declaraciones idénticas, pero que manejan el pixeldata de manera muy diferente. Esto nos da la ventaja de usar una tabla de búsqueda para obtener el método correcto de "convertidor". Esto debe hacerse ya sea en el constructor o dondequiera que el mapa de bits de imagen se asigna, como esto:

Private 
FLookup: Array[pf8bit..pf32bit,pf8bit..pf32bit] of TSomeDataProc; 

Procedure TMyClass.Create; 
Begin 
    Inherited; 
    FLookup[pf8bit,pf16bit]:=ProcessSomeData08x565; 
    FLookup[pf16bit,pf24Bit]:=ProcessSomeData565x888; 
end; 

Cada vez que necesitamos para convertir píxeles simplemente buscar el método correcto y lo usamos. La sintaxis sigue siendo la misma para todos los procedimientos, por lo que no debemos preocuparnos por "cómo" funciona cada procedimiento. En lo que respecta a nuestra clase, todos tienen el mismo aspecto.

Procedure TMyClass.ConvertTo(aFormat:TpixelFormat); 
Begin 
// Get function for the correct pixel converter 
FConvertProc:=FLookup[CurrentFormat,aFormat]; 

//Use the pixel converter 
FConvertProc(GetSourcePixelAddr(x,y),GetTargetPixelAddr(x,y)); 
end; 

La pregunta es: ¿Se este tipo de encasillamiento (por ejemplo: Const a byte o cualquier tipo de registro definido) sobrevivir bajo 64 bits? Personalmente no puedo ver por qué no, pero Embarcadero ha sido un poco vago con respecto al nuevo modelo de "seguridad" y el uso de punteros, por lo que me resulta un poco difícil proteger mi código para el futuro.

+1

No puedo ver cómo se escribe de esa manera en lugar de: 'ProcessSomeData (Const aInput : Byte; var aOutput: Word); ' –

+1

No pasa un puntero a ese código de ejemplo, ¿verdad? Por curiosidad, ¿qué pasa con el sistema de tipo incorporado, qué velocidad de puntero? –

+0

@Sertac Speed ​​es lo mismo aquí. Existe una sutil diferencia entre un parámetro sin tipo var var y un parámetro const typeless y un puntero genérico: un parámetro const type no debe modificarse, mientras que un puntero siempre se puede modificar. Y el uso de una var sin letra puede evitar escribir algunos caracteres^en tu código: PWord (aOutput) ^: = 13 por ejemplo. El ensamblador generado será el mismo que word (aOutput): = 13. –

Respuesta

3

Dado que tales trucos se utilizan en el RTL, no veo la desaprobación de un parámetro var o const typeless sin una gran cantidad de código de ruptura.

Embarcadero hace todo lo posible para mantener la mayor compatibilidad posible.

Incluso deberían incluir el asm en línea en el compilador de 64 bits, después de haber hecho alguna notificación sobre el uso de un ensamblador externo.

Y tal modificación no tendrá nada que ver con el modelo de 64 bits, mientras que el ensamblador x86-64 era una nueva pieza de código para escribir.

Así que deberías publicar esta pregunta del grupo de noticias oficial de Embarcadero, pero creo que no tienes que preocuparte por esto.

+0

Allen Bauer ya informó en un podcast reciente en http://www.delphi.org que el ensamblaje en línea sería compatible (con algunas limitaciones) en el compilador Delphi de 64 bits. –

+0

@Remy Sí, esto es lo que dije. Un buen movimiento hacia atrás. Hubo algún tipo de pánico en los grupos de noticias cuando dijeron sobre deshacerse del ensamblador en línea en el compilador Delphi de 64 bits. La nueva edición "Starter" también es algo bueno. Pero cuando escuché a Allen hablar sobre el futuro de Delphi y un recolector de basura, comencé a sentir pánico nuevamente. ;) –

1

Tenga en cuenta que FPC ya cambió el parámetro CONST, aunque no en este caso.

Para el caso normal, ya no se garantiza CONST por referencia para todas las convenciones de llamadas, pero sigue lo que especifique el ABI respectivo. Se garantiza que un nuevo tipo de parámetro, CONSTREF, será por referencia.

Al igual que todas las roturas de compatibilidad, es el problema que en TP/Delphi CONST siempre es por ref, pero TP/Delphi también es siempre x86.

Entre otras, cambian todas las funciones de STDCALL, como p. IUnknown.QueryInterface:

http://wiki.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed

La razón es más o menos que en estos casos, la información ABI x86 entró en la interfaz genérica, algo que no es compatible con la arquitectura cruzada. Entonces uno tiene que adivinar si es parte del lenguaje o parte de la implementación x86 del lenguaje.

Tenga en cuenta que IUnknown también se utiliza en otras plataformas, como p. Firefox 'XPCOM

Delphi también podría llegar a tales inconvenientes, pero creo que afectarán principalmente funciones/métodos con requisitos explícitos de convención de llamadas, porque se puede cambiar la convención interna para satisfacer las necesidades, pero prácticamente no se puede cambiar el resto del mundo ((XP) COM o librerías C (++) existentes) para adaptarse al código existente en Delphi

Cuestiones relacionadas