vb.net vb6 string-length

Longitud de cadena con nulo embebido en vb.net



vb6 string-length (2)

En VB.NET (y C #) las cadenas se tratan de manera muy similar a como están en VB6, y es que tienen una longitud explícita que no se basa en ningún carácter o caracteres particulares contenidos en ellas.

Con respecto a RichTextBox, simplemente parece que no es compatible con un carácter nulo incorporado.

Tengo una pregunta simple: ¿cómo vb.net determina la longitud de la cadena y trata la terminación de la cadena?
Sé que en C (y su familia) el carácter nulo es el final de la cadena. En vb6, el carácter nulo no tiene efecto en la terminación de la cadena, pero en vb.net parece estar nublado.
Asuma este código en vb6:

Private Sub Command1_Click() Dim Str As String Str = "Death is a good user," & Chr(0) & " Yes I''m good" RichTextBox1.Text = Str RichTextBox1.Text = RichTextBox1.Text & vbNewLine & Len(Str) End Sub

Esto que sucede cuando se ejecuta este código:

Y está bien. Este es un código similar en C :

#include "stdafx.h" #include <string.h> int main(int argc, char* argv[]) { char *p="Death is a good user,/0 Yes I''m good"; printf("String:%s/nString length:%d/n",p,strlen(p)); return 0; }

Y esto es lo que pasa:

Lo cual está bien también según las reglas de C , pero aquí está el mismo código en vb.net:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim str As String = "Death is a good user," & Chr(0) & " Yes I''m good" RichTextBox1.Text = str RichTextBox1.Text &= vbNewLine & str.Length End Sub

Y que pasa:


Lo cual no parece correcto!

Editar 1 : escribir en un archivo parece ser correcto:

Edit 2 : Mark y tcarvin sugieren que puede ser un problema de UI pero no explica por qué vb6 muestra una cadena completa.

Edición 3 : Sé que Windows y su API, interfaz de usuario, ... están escritos en C , por lo que sería normal que reaccionen como C , pero como mostré anteriormente, no lo hacen.


Hay tres tipos de cadenas distintas utilizadas en los fragmentos por las bibliotecas de soporte de tiempo de ejecución subyacentes:

  • BSTR, utilizado por VB6. Es un tipo de automatización COM utilizado por todos los controles ActiveX que pueden almacenar una cadena Unicode e incluye una longitud explícita. BSTR por lo tanto puede almacenar ceros incrustados.
  • C strings, utilizado por el lenguaje C. No se almacena ninguna longitud explícita, un cero indica el final de la cadena. El winapi está basado en C y utiliza cadenas C en sus funciones.
  • System.String, el tipo de cadena .NET y utilizado en cualquier código .NET. Similar a un BSTR, también tiene un campo de longitud explícito y puede almacenar cadenas con ceros incrustados.

En los tres casos, la interoperabilidad necesita ser utilizada por las bibliotecas de soporte de tiempo de ejecución subyacentes para hacer que la cadena sea visible:

  • VB6 usa un control ActiveX para RichEditBox. Exactamente cómo se ve el control es difícil de adivinar, es bastante específico de VB6 y se llama richtx32.ocx. También utiliza el control richedit nativo de Windows (riched32.dll) por lo que el control ActiveX actúa como un contenedor para hacer que el control nativo de Windows se pueda utilizar en una aplicación VB6. Ha demostrado de manera concluyente que respeta el comportamiento de un BSTR y maneja ceros incrustados, como cualquier control ActiveX.

  • El programa C utiliza la biblioteca C Runtime Library, que a su vez implementa printf () llamando a la función de consola winapi, WriteConsole (). Esta función api está basada en C pero el buck ya se detuvo en printf (), un cero incrustado es un terminador de cadena para esa función. No hay sorpresas aquí.

  • El programa Winforms utiliza la clase .NET RichEditBox, un contenedor administrado para el control de Windows nativo riched20.dll. El mecanismo subyacente es pinvoke, casi todas las propiedades y métodos de la clase se implementan pinvoking SendMessage () para enviar mensajes como EM_SETTEXTEX, el mensaje que altera el texto mostrado por el control. Esta es también una API basada en C, un cero actúa como un terminador de cadena. A diferencia del contenedor richtx32.ocx, la clase de contenedor .NET RichEditBox no hace un esfuerzo para manejar adecuadamente cadenas con ceros incrustados. Simplemente pasa la cadena tal como está y lo deja al marshaller pinvoke para convertir la cadena .NET en una cadena C. Que no tiene otra opción que truncar la cadena en el cero ya que las cadenas C no tienen un campo de longitud.