Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Lazarus, FreePascal, Kylix, etc. (https://www.clubdelphi.com/foros/forumdisplay.php?f=14)
-   -   Problema con una excepción que no consigo resolver. (https://www.clubdelphi.com/foros/showthread.php?t=81770)

Pedrote 16-12-2012 14:15:41

Problema con una excepción que no consigo resolver.
 
El código es el siguiente:
Código Delphi [-]
......
.....
function TForm1.GetValIni(secc, val: string): string;
begin
  INI := TINIFILE.Create(Config);
  Result := INI.ReadString(secc, val, '');
  INI.Free;
end;

// Configura los parámetros de conexión a MSSQL
function TForm1.ObtenerDatosConnDB: boolean;
begin
  if CheckValIni('BD', 'Inst') and CheckValIni('BD', 'Usuario') and
    CheckValIni('BD', 'Usuario') then
  begin
    MSSQLConnection1.HostName := GetValIni('BD', 'Inst');
    MSSQLConnection1.UserName := GetValIni('BD', 'Usuario');
    MSSQLConnection1.Password := descifrar(GetValIni('BD', 'Pass'));
    Result := True;
    exit;
  end;
  Result := False;
end;

// Obtiene el nombre de la BD del ejercicio de año actual
function TForm1.ObtenerBDEjActual: string;
begin
  if ObtenerDatosConnDB then
  begin
    MSSQLConnection1.DatabaseName := 'COMU0001';
    MSSQLConnection1.Connected := True;
    if MSSQLConnection1.Connected then
    begin
      SQLQuery1.SQL.Text := 'SELECT [CONEXION] ' +
                            'FROM ejercici ' +
                            'WHERE [ANY] = '
                                   + '''' + FormatDateTime('yyyy', Now) + ''';';
      SQLQuery1.Open;
      Result := SQLQuery1.FieldByName('CONEXION').AsString;
      SQLQuery1.Close;
      exit;
    end;
    MSSQLConnection1.Connected := False;
  end;
end;               
...
...
procedure TForm1.Button3Click(Sender: TObject);
var
  prueba: string;
begin
    prueba := ObtenerBDEjActual;
    ShowMessage(prueba);
end;

El problema es al pulsar por segunda vez el botón que me genera una excepción de la clase 'External: SIGSEGV', la primera vez obtengo sin problemas los datos de la query. ¿Cómo puedo solucionarlo?. Gracias de antemano.

Ñuño Martínez 16-12-2012 18:36:43

Los errores SIGSEGV se producen porque se intenta acceder a memoria fuera del marco de memoria de la aplicación. Normalmente se debe a que se olvidó crear algún objeto o se destruyó algún objeto y luego se intentó usar. La única forma de descubrir lo que falla es saber en qué punto se produce el error.

Por otro lado, ¿por qué creas y destruyes el objeto INI cada vez que accedes a una variable? Eso es una merma de rendimiento enorme. Lo mejor es que cargues el archivo INI al principio de ObtenerDatosConnDB, obtengas todos los valores, y destruyas el objeto antes del IF.

De todas formas, ¿te compila? Porque estás usando cadenas de caracteres en lugares donde se esperan expresiones booleanas. A mi nunca me deja compilar cosas así (Free Pascal).

Pedrote 16-12-2012 18:50:59

Ya lo solucione, era un objeto que no estaba creado. Respecto a lo del objeto INI tienes razón, pero es que no lo uso solo para obtener los parámetros de conexión de la BD si no para otras configuraciones de la aplicación FTP, ciertos directorios, etc. ¿Ves conveniente hacerme una función especifica que me recoja las variables de cada determinada sección del INI?. Yo no veo donde dices que mezclo tipos :S compilar compila.

pedrolazarus 16-12-2012 22:44:51

Cita:

Empezado por Pedrote (Mensaje 451899)
El código es el siguiente:

El problema es al pulsar por segunda vez el botón que me genera una excepción de la clase 'External: SIGSEGV', la primera vez obtengo sin problemas los datos de la query. ¿Cómo puedo solucionarlo?. Gracias de antemano.

Nada, no habia visto q lo solucionaste.

Ñuño Martínez 18-12-2012 12:19:21

Cita:

Empezado por Pedrote (Mensaje 451903)
Respecto a lo del objeto INI tienes razón, pero es que no lo uso solo para obtener los parámetros de conexión de la BD si no para otras configuraciones de la aplicación FTP, ciertos directorios, etc. ¿Ves conveniente hacerme una función especifica que me recoja las variables de cada determinada sección del INI?

No, no es conveniente. Lo que debes hacer, entonces, es crear el objeto INI en una unidad (por ejemplo, uno que se llame "config.pas") y acceder a él cuando necesites obtener información.

Código Delphi [-]
UNIT config;
(* Carga y permite el acceso a la configuración. *)

INTERFACE

  CONST
  (* Nombre del archivo de configuración. *)
    ArchivoConfiguracion = 'config.ini';

(* Devuelve el valor de configuración solicitado. *)
  FUNCTION GetValIni (secc, val: STRING): STRING;

IMPLEMENTATION

  USES
    IniFiles;

  VAR
  (* Contiene el archivo de configuración. *)
    ArchivoIni: TIniFile;

(* Devuelve el valor de configuración solicitado. *)
  FUNCTION GetValIni (secc, val: STRING): STRING;
  BEGIN
    GetValIni := ArchivoIni.ReadString (secc, val, '');
  END;

INITIALIZATION
(* Crea y carga el objeto. *)
  ArchivoIni := TIniFIle.Create (ArchivoConfiguracion);
FINALIZATION
(* Destruye el objeto. *)
  ArchivoIni.Free;
END.
Esto mejora el rendimiento, a costa de usar un poco más de memoria.

Cita:

Empezado por Pedrote (Mensaje 451903)
Yo no veo donde dices que mezclo tipos :S compilar compila.

Aquí:
Código Delphi [-]
  if CheckValIni('BD', 'Inst') and CheckValIni('BD', 'Usuario') and
    CheckValIni('BD', 'Usuario') then
Se supone que CheckValIni devuelve STRING pero los IF esperan un BOOLEAN. En FreePascal no compila, y al menos cuando usaba Delphi 6 tampoco.


La franja horaria es GMT +2. Ahora son las 20:30:01.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi