Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-05-2010
Aldo Aldo is offline
Miembro
 
Registrado: ene 2004
Posts: 46
Poder: 0
Aldo Va por buen camino
UDFs y Delphi 2010

Hola a todos.

Estoy intentando desarrollar una DLL que tiene algunas funciones de usuarios para Firebird ( UDF ) y lo estoy programando en Delphi 2010.

El problema que presento es que una función debe devolver un PCHAR y en lugar de devolverme la cedena completa, solo me está devolviendo el primer carácter de dicha cadena.

Anteriormente tenía otra UDF similar programada con Delphi 5 y funciona correctamente.

Se que tiene algo que ver con el nuevo tratamiento de los Strigs y Pchars en Delphi 2010, pero la verdad es que no se me ocurre como solucionarlo.

Os agradezco de antemano el tiempo prestado por leer esto e intentar ayudarme.

Un saludo
Responder Con Cita
  #2  
Antiguo 13-05-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Será más fácil que alguien te pueda ayudar si pones el código de la función, no crees?
Responder Con Cita
  #3  
Antiguo 13-05-2010
Aldo Aldo is offline
Miembro
 
Registrado: ene 2004
Posts: 46
Poder: 0
Aldo Va por buen camino
OK. Creo que lo mejor es lo que dices.

Aquí os va part edel código que tiene una clase para tratar un String y poder convertirlo en Pchar para que sea devuleto por la UDF en cuestión.

Código Delphi [-]
...
Type
   TUDFString = class
  private
    FString: PChar;
    FSize: Integer;
    FLength: Integer;
    procedure SetPChar(Value: PChar);
    function GetString: String;
    procedure SetString(Value: String);
    procedure SetSize(Value: Integer);
  public
    constructor Create;
    destructor Destroy; override;
    property AsString: String read GetString write SetString;
    property AsPChar: PChar read FString write SetPChar;
    property StrLength: Integer read FLength;
    property StrSize: Integer read FSize write SetSize;
  end;
...
threadvar
  gResult: TUDFString;
...

implementation

const
  ShrinkLen = 100;

constructor TUDFString.Create;
begin
  FString := nil;
  SetSize(ShrinkLen);
  FLength := 0;
end;

destructor TUDFString.Destroy;
begin
  if (Self <> nil) and (FSize > 0) then
    ReallocMem(FString, 0);
  inherited;
end;

procedure TUDFString.SetPChar(Value: PChar);
begin
  FLength := StrLen(Value);
  SetSize(FLength);
  StrCopy(FString, Value);
end;

function TUDFString.GetString: String;
begin
  result := String(FString);
end;

procedure TUDFString.SetString(Value: String);
begin
  if Self <> nil then begin
    FLength := Length(Value);
    SetSize(FLength);
    StrPCopy(FString, Value);
  end;
end;

procedure TUDFString.SetSize(Value: Integer);
begin
  if (Value > FSize) or
     (Value <= FSize - ShrinkLen) then begin
    ReallocMem(FString, Value + 1);
    FSize := Value;
  end;
end;
...

Ahora la declaración de la UDF

Código Delphi [-]
function T_AlgoToStr( var nFVToCheck: Integer ): PChar; cdecl; export;

La implemetación de dicha función. Se asume que la variable gResult se ha creado en Initialization section de la DLL.

Código Delphi [-]
function T_AlgoToStr( var nFVToCheck: Integer ): PChar; cdecl; export;
   function IsValueOk( nValue: Integer ): Boolean;
   begin
      .....
      Result := True;
   end;
   
   function GetAlgoAsStr( nValue: Integer ): String;
   begin
      case nValue of
         1 : Result := 'Cadena 1' ;
         ...
         else
            Result := 'Cadena else';   
      end;
begin
   Result           := '';
   if  not IsValueOk( nFVToCheck ) then
      Exit;
   
   gResult.AsString := GetAlgoAsStr( nFVToCheck ); 
   Result           := gResult.AsPChar; 
end;

NOTA: Esto funciona correctamente en Delphi 5 pero no en Delphi 2010 que en vez de devolver la cadena completa solo devuelte el primer elemento de la cadena.
Responder Con Cita
  #4  
Antiguo 13-05-2010
Avatar de defcon1_es
defcon1_es defcon1_es is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuenca - España
Posts: 533
Poder: 21
defcon1_es Va por buen camino
Cita:
Empezado por Aldo Ver Mensaje
NOTA: Esto funciona correctamente en Delphi 5 pero no en Delphi 2010 que en vez de devolver la cadena completa solo devuelte el primer elemento de la cadena.
Ciertamente es por lo que dices, en Delphi 2010 un PChar se trata como PWideChar.

Para evitar problemas con esto, deberías especificar el tamaño del caracter con el que estás trabajando (2 bytes), como he señalado en negrita.
Código Delphi [-]
procedure TUDFString.SetSize(Value: Integer);
begin
  if (Value > FSize) or
     (Value <= FSize - ShrinkLen) then begin
    ReallocMem(FString, (Value + 1) * Sizeof(WideChar));
    FSize := Value;
  end;
end;
...
No obstante, puedes mirar en la ayuda de Delphi 2010, ms-help://embarcadero.rs2010/rad/Enabling_Applications_for_Unicode.html

Otra buena referencia para trabajar con UNICODE la tienes aqui:
http://delphi.about.com/od/objectpas...-in-delphi.htm

Salu2
__________________
Progress Openedge
https://abevoelker.com/progress_open...dered_harmful/


Delphi forever...
Responder Con Cita
  #5  
Antiguo 14-05-2010
Aldo Aldo is offline
Miembro
 
Registrado: ene 2004
Posts: 46
Poder: 0
Aldo Va por buen camino
Muchas gracias por tu consejo, pero la verdad es que no se ha resuleto el problema con lo que me has comentado.

Hay algo que no he aclarado y es que he hecho una pequeña aplicación de testeo en la que he agregado la unit en la que está programada la función T_AlgoToStr y en ese caso SIEMPRE me ha funcionado bien, el problema es cuando ejecuto una sentencia SQL en el Marathon por ejemplo en la que involucro la función UDF, es solo ahí donde en vez de devolverme la cadena completa, me devuelve solamente la primera letra de la cadena.

Aclaro que uns función UDF similar programada en Delphi 5 funciona correctamente.

Por otra parte se me ha olvidado poner el ejemplo de la declaración de la función en el firebird 2.1 y es la siguiente:

Código SQL [-]
DECLARE EXTERNAL FUNCTION T_AlgoToStr
INTEGER
RETURNS CSTRING(255) 
ENTRY_POINT 'T_AlgoToStr' MODULE_NAME 'Library_UDF';

Intentaré seguir investigando. Pero agradezco cualquier tipo de ayuda, porque me urge el tema.

Un saludo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Hacer que Delphi 2010 luzca como Delphi 7 jorosmtz La Taberna 0 11-04-2010 22:45:36
Delphi 2010 tec Varios 1 19-01-2010 19:05:55
Problema Udfs cincosoft Firebird e Interbase 5 16-09-2008 23:06:48
UDFs Linux RESP 3.0 Firebird e Interbase 2 26-01-2006 16:10:44
Problemas com UDFs jwmoreira Firebird e Interbase 3 17-06-2004 19:53:01


La franja horaria es GMT +2. Ahora son las 01:00:55.


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