Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-06-2007
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
String, PChar y UNICODE

A las wenas.

Por fin, este fin de semana culmino mi mudanza y podré disponer de mi ordenador. ¡Viva! Así que voy a poder trabajar en cosas que tenía estancadas desde hace meses. Después de esta información de interés general , voy a la pregunta. Al principio parece complicada, pero no creo que sea muy difícil dar con una solución. Lo que pasa es que después de tanto tiempo pues estoy desentrenado.

Estoy creando una envolvente para una librería. Dicha librería permite el uso de UNICODE en distintos formatos (ASCII, UTF-8, UTF-16 y UTF-32). Por ahora estaba utilizando PChar ya que era lo más flexible (además, la librería está escrita en C y este tipo se ajusta muy bien a este lenguaje) pero utilizar esto no permite manejar las cadenas como en Pascal (p.ej. no puedo escribir Cadena := Cadena1 + Cadena2; con lo que realizar concatenaciones y comparaciones se complica bastante). Sé que Delphi tiene un tipo de cadena para utilizar UNICODE, pero me preocupa que luego no pueda pasar estas cadenas a la librería por incompatibilidad. Para que os hagáis una idea, estaba pensando en algo como esto:
Código Delphi [-]
UNIT ejemploLibreriaCadenas;

INTEFACE
  PROCEDURE ProcedimientoCadena (Cadena: STRING);

IMPLEMENTATION

{ Este es el enlace a la función C que quiero llamar. }
  PROCEDURE _ProcedimientoCadena_C_ (Cadena: PCHAR); CDECL; EXTERN 'libreria.dll' NAME 'procedimiento_cadena';

{ Este es el 'molde' que voy a utilizar. }
  PROCEDURE ProcedimientoCadena (Cadena: STRING);
  VAR
    CadenaTmp: PCHAR;
  BEGIN
  { Transformamos el STRING en un PCHAR que pueda ser manejado como
    cadena en C. }
    Cadena := Cadena + #0: { En C una cadena termina con el carácter 0. }
    CadenaTmp := PCHAR (@Cadena[1]);
  { Ahora ya podemos llamar al procedimiento. }
    _ProcedimientoCadena_C_ (CadenaTmp);
  END;

END.
Sé que esto (o algo muy similar) funciona porque ya lo utilicé una vez. Mi incógnita es: ¿Qué tipo de datos utiliza Delphi para manejar las cadenas UNICODE? ¿Y alguno de vosotros sabe cómo almacena esta cadena en memoria en los distintos formatos (ASCII, UTF-8, UTF-16 y UTF-32)?

Casi lo olvido: Gracias por adelantado.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine

Última edición por Ñuño Martínez fecha: 01-06-2007 a las 16:12:08.
Responder Con Cita
  #2  
Antiguo 01-06-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Ñuño
¿Qué tipo de datos utiliza Delphi para manejar las cadenas UNICODE?
Creo que al menos uno de los tipos disponibles para trabajar con Unicode en Delphi es el tipo "WideString". Y hasta ahí llego...
Responder Con Cita
  #3  
Antiguo 01-06-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Cita:
Empezado por Ñuño Martínez
Después de esta información de interés general
Gracias por mantenernos informados

En delphi tienes el tipo WideString para manejar caracteres unicode. Donde cada carácter esta representado por 2 bytes. En su manejo no se diferencia de un string normal y hay toda una serie de funciones (empiezan por Wide) que manejan este tipo de cadenas.

En el momento de pasarla a la función en C tendrás que convertir la cadena a uno de los formatos que admite tu función, por ejemplo UTF-8. Dependiendo de la versión de delphi con la que cuentes, puedes usar la función UTF8Encode que a partir de un WideString te devuelve un string en formato UTF-8. A partir de ese momento lo manejas como un string normal. Es decir:
Código Delphi [-]
PROCEDURE ProcedimientoCadena (Cadena: WIDESTRING);
  BEGIN
    _ProcedimientoCadena_C_ (PCHAR(UTF8Encode(Cadena)));
  END;

PD: Las cadenas en delphi no son tan diferentes a C, internamente una variable string es un puntero a una cadena terminada en carácter nulo, exactamente igual que en C, por eso se puede hacer un typecast de un string a un PChar sin necesidad de añadir el carácter nulo.
Responder Con Cita
  #4  
Antiguo 01-06-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Y por si tu versión de delphi no cuenta con la función UTF8Encode, aquí te dejo una alternativa usando la API de windows.
Código Delphi [-]
function UTF8Encode2(Str: WideString): String;
var
  Size: Integer;
begin
  Size:= WideCharToMultiByte(CP_UTF8,0,PWideChar(Str),-1,nil,0,nil,nil);
  if Size > 0 then
  begin
    SetLength(Result,Size);
    WideCharToMultiByte(CP_UTF8,0,PWideChar(Str),-1,PChar(Result),Size,nil,nil);
  end else
    Result:= '';
end;
Responder Con Cita
  #5  
Antiguo 04-06-2007
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Gracias a los dos por las respuestas. Tomo nota, que seguro que sirve. Este finde estuve investigando con AnsiString, que no es exactamente lo que necesito pero que puede sacarme de algún apuro.

A ver cómo me lo monto.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #6  
Antiguo 04-06-2007
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Pues en la lista de correo de FreePascal (no es que no me fiara, sino que en este caso busqué una segunda opinión ) me han dado una solución similar. Lo que me han dicho también es que WIDESTRING no usa una codificación UTF-16 sino que depende de la plataforma (por ejemplo, en Win9x parece que utiliza UCS-2), de ahí que existan funciones como la UTF8Encode por ejemplo.

Al final creo que voy a duplicar las funciones que permiten el uso de UNICODE, de forma que haya dos: una para ANSISTRING/STRING y otra para WIDESTRING. Así me evito quebraderos de cabeza y me quedará resultón.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
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
CopyFile String Pchar FGarcia Varios 7 14-08-2006 18:12:07
pasar contenido de pchar a string coletaun Varios 14 25-07-2006 17:46:09
Compatibilidad entre PChar y String vick Conexión con bases de datos 5 24-10-2005 21:50:35
¿como pasar de String dentro de un PChar? Moises22 Varios 6 27-09-2005 15:43:47
Pchar y String superhopi Varios 8 19-08-2004 09:54:06


La franja horaria es GMT +2. Ahora son las 23:54:33.


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