PDA

Ver la Versión Completa : ResourceString y punteros


geolife
27-05-2018, 18:36:47
Hola amig@s,

Estoy intentando trabajar con Gnugettext y en un programa original hay multitud constantes de array que necesitan ser traducidas;

Como las constantes no se inicializan en tiempo de ejecución en los cambios de idiomas he apuntado las mismas en forma de punteros a un ResourceString; pero delphi aunque deja ejecutar la acción no presenta ningún dato al llamar al array y al cerrar provoca una excepción;

Este sencillo código de ejemplo, funciona correctamente en Lazarus, con lo que no se si hay algo en Delphi que requiera alguna directiva especial u otro cambio en el código que desconozco.:confused:


Adjunto el código:


unit U_Translate;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

Resourcestring

RSEstaciones1 = 'Primavera';
RSEstaciones2 = 'Verano';
RSEstaciones3 = 'Otoño';
RSEstaciones4 = 'Invierno';

Const
CEstacion: Array [1..4] of ^String = (@RSEstaciones1,@RSEstaciones2,@RSEstaciones3,@RSEstaciones4);

var
Form1: TForm1;


implementation


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage (CEstacion[1]^);
end;

end.

Neftali [Germán.Estévez]
28-05-2018, 09:57:35
En mi blog tienes un par de artículos con ejemplos sobre el proceso completo con GNUGettext con Delphi.
Revísalos a ver si te son de ayuda.
Pruébalo también sobre un proyecto pequeño y luego sobre el que tú tienes a ver si eso te da pistas.

geolife
28-05-2018, 10:07:36
Hola Neftali!

Gracias por contestar; precisamente ha sido a través de los ejemplos que nos facilitas en tu Blog como me pude iniciar en el uso de esta librería para tener una aplicación multi-idioma, y todo funciona bastante bien en general.

El único problema es que en tiempo de ejecución no es capaz de actualizar un array de constantes adheridos a un Resourcestring como el ejemplo (solo lo hace si reiniciamos la aplicación por completo).

Entonces para solventar esta cuestión está el truco de enlazar las constantes del array directamente con las posiciones de memoria (de los resourcestring) usando punteros, lo cual funciona bien en Lazurus, pero no lo hace en Delphi. El código de ejemplo compila correctamente pero el showmessage se muestra en blanco...y al cerrar provoca una expepción!




;526593']En mi blog tienes un par de artículos con ejemplos sobre el proceso completo con GNUGettext con Delphi.
Revísalos a ver si te son de ayuda.
Pruébalo también sobre un proyecto pequeño y luego sobre el que tú tienes a ver si eso te da pistas.

Casimiro Notevi
28-05-2018, 11:04:22
Seguramente es porque, precisamente, son constantes y no se les puede cambiar su valor.
¿Has probado si funciona igual si no son const?

geolife
28-05-2018, 11:14:00
Hola Casimiro!

Si, acabo de probar usando un Var en vez de Const; y tenemos el mismo resultado. Adjunto el ejemplo simplificado con puntero y sin el, en el primer caso Showmessage funciona bien, en el segundo caso no lo hace...


unit U_Translate;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
public
end;

Resourcestring
RS1 = 'Primavera'; RS2 = 'Verano'; RS3 = 'Otoño'; RS4 = 'Invierno';

var
Form1: TForm1;
CEstacion: Array [1..4] of String = (RS1,RS2,RS3,RS4); // Normal
PCEstacion: Array [1..4] of ^String = (@RS1,@RS2,@RS3,@RS4); // Puntero

implementation {$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage (CEstacion[1]);
ShowMessage (PCEstacion[1]^);
end;

end.


Seguramente es porque, precisamente, son constantes y no se les puede cambiar su valor.
¿Has probado si funciona igual si no son const?

geolife
28-05-2018, 16:07:45
@Neftali [Germán.Estévez] ; @Casimiro Notevi

Gracias por vuestra ayuda, finalmente al plantear también la cuestión en stackoverflow hay un camino que sugiere Stefan Glienke y lo dejo aquí compartido, por si cualquiera se encuentra ante el mismo problema.

https://stackoverflow.com/questions/50562012/using-pointers-and-resourcestring

Básicamente se trata de lo siguiente:

Resourcestring
RS1 = 'Primavera'; RS2 = 'Verano'; RS3 = 'Otoño'; RS4 = 'Invierno';
const
CEstacion: array [1..4] of PResStringRec = (@RS1,@RS2,@RS3,@RS4);
procedure show;
begin
ShowMessage(LoadResString(CEstacion[1]));
end;