2009-09-09 9 views
7

Tengo que convertir una aplicación legacy de gran tamaño a Delphi 2009 que usa cadenas, AnsiStrings, WideStrings y datos UTF8 por todas partes y me cuesta entender cómo funcionan los nuevos tipos de cadenas y cómo deben usarse.¿Cómo funcionan los nuevos tipos de cadenas en Delphi 2009/2010?

La aplicación es totalmente compatible con Unicode con TntUnicodeControls y hay archivos DLL de terceros que requieren cadenas en codificaciones específicas, principalmente UTF8 y UTF16, por lo que la tarea de conversión no es tan trivial como uno sospecha.

Especialmente tengo problemas con las llamadas de DLL C y elijo el tipo correcto. También tengo la impresión de que hay muchas conversiones de cadenas implícitas, porque una de las DLL parece siempre recibir cadenas codificadas en UTF-8, sin importar cómo esté codificada la cadena Delphi.

¿Puede alguien dar una breve descripción de los nuevos tipos de cadenas Delphi 2009 UnicodeString y RawByteString, quizás algunos consejos de uso y posibles dificultades al convertir una aplicación anterior a 2009?

+0

Las repeticiones de CodeRage 4 se han puesto en línea; vea http://www.delphifeeds.com/go/s/60421 y http://conferences.embarcadero.com/coderage/sessions –

Respuesta

8

Mire mi CodeRage 4 charla sobre "Usar Unicode y otras codificaciones en sus programas" este viernes, o espere hasta que la reproducción esté disponible en línea.

Voy a cubrir algunas codificaciones y explicar el formato de la cadena.

Las diapositivas estarán disponibles en breve (intentaré ponerlas en línea hoy) y contienen muchas referencias a cosas que debería leer en Internet (pero debo admitir que olvidé el enlace a Joel en Unicode que eed3si9n al corriente).

Editará esta respuesta hoy con las cargas y los enlaces.


Editar:

Si usted tiene una pequeña muestra donde se puede demostrar que su C/C++ DLL recibe las cadenas UTF-8 codificados, pero creía que debían ser codificados de otra manera, por favor, publicarlo (correo yo, casi cualquier cosa en pluimerers dot com me llega, especialmente si usas mi nombre antes del signo at).

Los materiales de sesión ahora pueden ser downloaded, incluida la sesión "Uso de Unicode y otras codificaciones en sus programas".

Estos son enlaces de esa sesión:

Leer siguientes:

  1. Marco Cantu, Whitepaper “Delphi and Unicode
  2. Marco Cantu, Presentación “Delphi and Unicode
  3. Nick Hodges, Whitepaper “Delphi in a Unicode World "

aspectos relevantes de línea de ayuda:

  1. What's New in Delphi and C++Builder 2009
  2. tipos de cadenas: Base: ShortString, AnsiString, WideString, UnicodeString
  3. tipos de cadenas: Unicode (including internal memory layouts of the string types)
  4. tipos de cadenas: Enabling for Unicode
  5. tipos de cadenas: RawByteString (AnsiString with CodePage $ffff)
  6. tipos de cadenas: UTF8String (AnsiString with CodePage 65001)
  7. Cadena < - > conversiones PChar: PChar fundamentals
  8. < de Cuerda -> PChar conversiones: Returning a PChar Local Variable
  9. < Cadena -> PChar conversiones: Passing a Local Variable as a PChar

espero que esto consigue que va. Si no, envíenme un correo electrónico e intentaré extender la respuesta aquí.

+0

Ese es un título extraño, teniendo en cuenta que Unicode no es una codificación, pero (para citar a Wikipedia): "Unicode se puede implementar mediante diferentes codificaciones de caracteres". – mghie

+0

Como hablante de inglés no nativo, no pude encontrar un título corto que cubriera el tema correctamente. Si tiene uno: por favor, hágamelo saber. Me gustaría cambiar el título. –

+0

No soy un hablante nativo tampoco, pero creo que el título, tal como está, contiene una declaración falsa, y eso es desafortunado ya que hay demasiados conceptos erróneos sobre Unicode de todos modos. "Usar Unicode y elegir codificaciones ..." sería más correcto. Sin embargo, como no conozco tu charla, no sé si es un título mejor. – mghie

11

Ver Delphi and Unicode, un libro blanco escrito por Marco Cantù y creo que The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!), escrito por Joel.

Un escollo es que el Win32 llamada a la API por defecto ha sido asignada para utilizar la versión en lugar de la versión A (ANSI) W (cadena de ancho), por ejemplo ShellExecuteA Si el código está haciendo código puntero complicado asumir disposición interna de AnsiString , se romperá Una alternativa es sustituir PChar con PAnsiChar, Char con AnsiChar, string con AnsiString, y anexar A al final de la llamada API de Win32 para esa parte del código. Después de que el código realmente compila y se ejecuta normalmente, puede refactorizar su código para usar string (UnicodeString).

+0

+1 excelentes enlaces. Ambas son lecturas muy interesantes. – jpfollenius

+0

Hice una pregunta similar sobre [actualizar una aplicación C++ Builder 2007] (http://stackoverflow.com/questions/1392409/what-do-i-need-to-know-to-upgrade-a-complex- application-from-cbuilder-2007-to-2). No todo será aplicable, pero algunos de los enlaces y respuestas que las personas proporcionaron podrían ser útiles para usted. –

0

Tenga en cuenta que no solo afecta al código de cadena real. También acierta el código donde PCHAR se utiliza para rastrear a través de búferes, o interfaz con API.

E.g. código de inicialización de encabezados que cargan la DLL dinámicamente (getprocedureaddress/loadlibray)

0

Parece que casi todos mis problemas provienen de la conversión automática en las asignaciones a UTF8String.

Ya tenía el código anterior usando UTF8String solo para ayudarme a pensar qué tipo de cadena debería contener una variable.

Al empezar a portar mi solicitud, he sustituido AnsiString con UTF8String por la misma razón, pero el código dependía de UTF8String ser sólo un alias (clásico) AnsiString

Ahora, con la conversión automática esa suposición ya no es cierto, lo que creó muchos problemas.

¡Tenga cuidado si usa UTF8String cuando transfiere del código Delphi anterior a 2009!

0

Otra cosa a tener en cuenta cuando se pasa cadena entre dlls construidos con diferentes versiones de Delphi o C++ Builder es que, a partir de 2009, la parte StrRec de AnsiStringBase ganó dos campos adicionales; codePage y elemSize. Son 2 bytes cada uno (entradas cortas), por lo que el tamaño de StrRec ahora es de 12 bytes en lugar de 8.Esto puede causar problemas de excepción de puntero no válidos con asignación y destrucción de memoria, incluso cuando la parte de datos de la cadena parece transferirse correctamente.

Cuestiones relacionadas