<-- Capítulo VII

Regresar a la página principal

Capítulo IX -->

Capítulo VIII

Cadenas (string) y Memoria

En este capitulo vamos a dar una breve introducción, de 2 temas que seguramente será de muy poco uso en VB, pero que algunas veces es necesario conocerlos para el manejo de algunas funciones API’S, por ejemplo, las funciones que vamos a ver a nivel de Cadenas o String, no ve ser necesario usarlas en VB, ya que dicho lenguaje presenta funciones que hacen el trabajo. Pero uno nunca sabe cuando uno puede usar estas funciones, inclusive para aquellos osados que programen en C entonces si necesitaran el conocer estas funciones.

CADENAS O STRING

En esta sección veremos algunas funciones API’S utilizadas para la manipulación de caracteres, para este proyecto es necesario: 3 Label o etiquetas, 1 listBox y 1 caja de texto o TextBox.

Luego peguen este código:

Ver Codigo

CharLower

Api: Declare Function CharLower Lib "user32" Alias "CharLowerA" (ByVal lpsz As String) As String

Función encargada de poner en minúscula una cadena de texto, dicha cadena se le pasa como único parámetro, y la función retorna la nueva cadena con todos los caracteres en minúscula.

CharLowerBuff

Api: Declare Function CharLowerBuff Lib "user32" Alias "CharLowerBuffA" (ByVal lpsz As String, ByVal cchLength As Long) As Long

Hace exactamente lo mismo que la función descrita arriba, con la diferencia que como segundo parámetro le pasamos la cantidad de caracteres que queramos poner en minúscula, es decir, con esta función podemos convertir en minúscula una porción de la cadena de caracteres.

CharUpper

Api: Declare Function CharUpper Lib "user32" Alias "CharUpperA" (ByVal lpsz As String) As String

Igual que la función CharLower con la diferencia que convierte los caracteres que están en minúscula en mayúsculas.

CharUpperBuff

Api: Declare Function CharUpperBuff Lib "user32" Alias "CharUpperBuffA" (ByVal lpsz As String, ByVal cchLength As Long) As Long

Igual que la función CharUpperBuff con la diferencia que convierte los caracteres que están en minúscula en mayúsculas.

IsCharAlpha

Api: Declare Function IsCharAlpha Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long

Determina si un carácter es “Alpha”, es decir, es cualquier letra del abecedario, ya sea en mayúscula o en minúscula, dicho carácter, se le pasa como primer parámetro en forma de “byte” lo cual significa que se le pasa el código ASCII. Si el carácter es del tipo “Alpha” entonces retornara un valor distinto de 0. En caso contrario retorna 0.

IsCharAlphaNumeric

Api: Declare Function IsCharAlphaNumeric Lib "user32" Alias "IsCharAlphaNumericA" (ByVal cChar As Byte) As Long

Determina si un carácter es del tipo “Alpha” numérico, es decir, todos los caracteres del abecedario incluyendo los números. Las condiciones del primer parámetro son iguales a IsCharAlpha.

IsCharLower

Api: Declare Function IsCharLower Lib "user32" Alias "IsCharLowerA" (ByVal cChar As Byte) As Long

Determina si un carácter esta en minúscula, si el carácter esta en minúscula la función retorna un valor distinto de 0.

IsCharUpper

Api: Declare Function IsCharUpper Lib "user32" Alias "IsCharUpperA" (ByVal cChar As Byte) As Long

Determina si un carácter esta en mayúscula, si el carácter esta en mayúscula la función retorna un valor distinto de 0.

lstrcat

Api: Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Función que concatena 2 cadenas, es decir, pega “lpString2” en “lpString1”, ejm:

Cadena1 = “Hola”

Cadena2 = “ Mundo”.

Cadena1 después de lstrcat = “Hola Mundo”

lstrcmp

Private Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Compara dos cadenas de caracteres, dicha comparación “es sensitiva a mayúsculas y minúsculas”, es decir, para esta función:

s1 = "String 1"

s2 = "string 1"

Estas cadenas, no son iguales, ya que “s1” tiene “S” y “s2” tiene “s”.

lstrcmpi

Api: Declare Function lstrcmpi Lib "kernel32" Alias "lstrcmpiA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Hace lo mismo que la anterior con la diferencia que “no es sensitiva”, es decir, para esta función:

s1 = "String 1"

s2 = "string 1"

Son iguales.

lstrcpy

Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Copia la cadena que hay en “lpString2” en “lpString1”.

lstrcpyn

Private Declare Function lstrcpyn Lib "kernel32" Alias "lstrcpynA" (ByVal lpString1 As String, ByVal lpString2 As String, ByVal iMaxLength As Long) As Long

Copia una cantidad de bytes específicos que hay en “lpString2” en “lpString1”. Dicha cantidad de bytes es pasada en el tercer parámetro de la función.

lstrlen

Api: Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long

Determina la longitud de la cadena de texto, pero dicha longitud dependerá del formato del texto, el valor que retorna será la cantidad en bytes, si la cadena es del tipo (ANSI) o retornara la cantidad de caracteres si el del tipo (UNICODE).

MEMORIA

En esta sección vamos a tratar las funciones básicas para tratar con la memoria del sistema, todos sabemos que con la introducción de Windows 95, se añadió lo que se llama memoria virtual, dicha memoria esta localizada en el disco duro, y el sistema la usa cuando la memoria ram se encuentra llena, en el proyecto que veremos a continuación trabajamos con la memoria RAM, pero las explicaciones de las funciones que veremos son análogas para el manejo de la memoria virtual.

Para este proyecto es necesario: 2 botones, y 2 etiquetas o label. Luego pegan este código:

Ver Codigo

Cuando arranquen y aprieten los botones, verán que las etiquetas se llenan con información, ustedes podrían preguntarse, ¿Para que hacer todo esto, si con solo asignar variable1=variable2, estamos listo?. Ciertamente, esto es un proceso un poco engorroso, pero algunas veces, para manipular algunas API’S es necesario tener en cuenta estas funciones primordialmente CopyMemory.

GlobalAlloc

Api: Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long

Función encargada de reservar un espacio en memoria, el primer parámetro puede tener una combinación OR de las siguientes constantes:

Private Const GMEM_FIXED = &H0 ‘ Reserva un espacio ya fijo, en la memoria.

Private Const GMEM_MOVEABLE = &H2 ‘ Reserva un especio el cual no esta fijo, es decir, Windows, tiene la libertad de moverlo.

Private Const GMEM_DDESHARE = &H2000

Private Const GMEM_SHARE = &H2000 ‘ Estas dos constantes, sirven para reservar un especio de memoria compartido.

Private Const GMEM_DISCARDABLE = &H100

Private Const GMEM_NOT_BANKED = &H1000 ‘

Private Const GMEM_LOWER = GMEM_NOT_BANKED

Private Const GMEM_NOTIFY = &H4000

Private Const GMEM_NOCOMPACT = &H10

Private Const GMEM_NODISCARD = &H20 ‘ Todas estas constante son ignorada por el sistema, solo se usa para mantener compatibilidad con aplicaciones de 16 Bits.

Private Const GMEM_ZEROINIT = &H40 ‘ Inicializa el contenido de la memoria con 0.

Como segundo parámetro “dwBytes”, le pasamos la cantidad de bytes que queremos reservar para dicha memoria.

En caso de no poseer suficiente espacio en la pila de memoria, la función retornara NULL, de lo contrario retorna el “handle” o identificador de la memoria, en caso de haber usado GMEM_FIXED la función retorna directamente el puntero de la memoria, es decir, la ubicación en donde almacenaremos nuestra información.

GlobalReAlloc

Api: Declare Function GlobalReAlloc Lib "kernel32" (ByVal hMem As Long, ByVal dwBytes As Long, ByVal wFlags As Long) As Long

Función que sirve para cambiar los atributos o tamaño a un “handle” de memoria ya creado. Como primer parámetro le pasamos el “handle” de la memoria, como segundo parámetro le pasamos el nuevo tamaño en bytes, y como tercer parámetro les pasamos los “flag” los cuales son los mismos que las constantes de la función GloballAlloc.

GlobalLock

Api: Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long

Función que bloquea el espacio de memoria asignado con GlobalAlloc, ¿Qué quiere decir bloquear?. Cuando creamos un espacio en memoria, sin usar la constante GMEM_FIXED, el sistema operativo esta en la autoridad de poder mover dicha información, esto puede ocasionar fallas en el programa. Imaginemos que tenemos una variable “a”, que esta en la posición 1 de la memoria , y le asignamos el valor de 5, si creamos la variable “a” con GlobalAlloc sin haber usado GlobalLock, cuando vayamos a consultar la variable “a” puede que Windows nos retorne un error, y esto se debe a que Windows pudo haber cambiado la posición en donde estaba la información de “a”, con GloballLock, nosotros lo que hacemos es fijar o bloquear ese espacio para que Windows no lo mueva y así poder trabajar dicho espacio sin problemas.

El único parámetro a usar es el “handle” de la memoria que nos retorna GlobalAlloc.

GlobalUnlock

Api: Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long

Lo que hace es desbloquear un “handle” de memoria.

GlobalFree

Api: Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long

Con esto liberamos el espacio de memoria que fue utilizado, dejando que otro programa pueda usar dicho espacio. Todo espacio que creamos con GlobalAlloc tiene que ser liberado, sino aunque cerremos el programa que manipulaba la memoria la información sigue estando contenida en la memoria RAM de la computadora.

CopyMemory

Api: Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Función encargada de copiar la información de un espacio de memoria a otro. Los dos primeros parámetro hablan por si solo, y el tercer parámetro es la longitud en bytes de la cantidad de información que queremos copiar.

FillMemory

Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (Destination As Any, ByVal Length As Long, ByVal Fill As Byte)

Llena el espacio en memoria, con la información que se le pasa en el tercer parámetro “fill”, es decir:

Fillmemory(espacio,4,65)

Aquí lo que estoy haciendo es que en la dirección de memoria contenido en la variable “espacio”, almacena 4 bytes, donde cada byte tendrá la letra “A”, si lo vemos como carácter o 65 si lo vemos como número. ¿Lo ven?. Llena el contenido de la memoria con la información pasada en “fill”.

Vayamos a los ejemplos, primero veamos el “command1”:

Dim espacio As Long

Dim espaciofijo As Long ‘ Declaro las dos variable que almacenaran la dirección de memoria reservada.

Dim num As Long, num2 As Long

num = 100

espacio = GlobalAlloc(GMEM_ZEROINIT, 4) ‘ Reservo 4 bytes de memoria, y los inicializo en 0

espaciofijo = GlobalLock(espacio) ‘ Fijo el espacio para que Windows no cambie la información.

CopyMemory ByVal espaciofijo, num, 4 ‘ Copio el valor de “num”, en la dirección de memoria de “espaciofijo”.

CopyMemory num2, ByVal espaciofijo, 4 ‘ Copio lo que hay en la dirección “espaciofijo” en la variable “num2”

Label2 = num2 ‘ Muestro el contenido “num2” que es igual al de “num1”

GlobalUnlock espaciofijo ‘ Desbloqueé el espacio que esta bloqueado, para liberarlo.

GlobalFree espacio ‘ Libero el espacio.

Dense cuenta de algo, la variable “espaciofijo” contiene la dirección de memoria donde almacenaremos información, es decir:

CopyMemory ByVal espaciofijo, num, 4

Es incorrecto pensar que “espaciofijo” ahora tiene el valor de “num”, NO!, la dirección que apunta “espaciofijo” contiene el valor de “num”, que es algo muy distinto. “espaciofijo” es una variable ubicado en X lugar de la memoria, cuyo numero de tipo “long” que contiene específicamente una dirección en la memoria. Espero que vean la diferencia. Para los conocedores de C seguro no habrá problema.

Vayamos al “command2”:

Dim espacio As Long

s1 = "Hola mundo!"

espacio = GlobalAlloc(GMEM_FIXED Or GMEM_ZEROINIT, Len(s1)) ‘ Reservamos un espacio ya fijo en la memoria, esto es gracias a la constante GMEM_FIXED es decir, no es necesario el uso de la función GlobalLock.

CopyMemory ByVal espacio, ByVal s1, Len(s1) ‘ Copiamos la cadena de caracteres “s1”, en la dirección de memoria que tiene almacenada la variable “espacio”.

s2 = String$(lstrlen(espacio), 0) ‘ Inicializamos el espacio de memoria donde almacenáremos el contenido de la dirección de memoria almacenada en la variable “espacio”.

CopyMemory ByVal s2, ByVal espacio, lstrlen(s1) ‘ Copiamos el contenido de la dirección que esta en “espacio” en la variable “s2”.

Label1 = s2

GlobalFree espacio ‘Liberamos dicho espacio.

Como pueden ver no es muy cómodo trabajar de esta manera, y mas cuando todo se pudo haber solucionado con s1 = s2, y listo!, pero resulta que algunas veces las funciones API’S de Windows nos regresan punteros de memoria que para visualizar su contenido tenemos que hacer lo antes expuesto arriba, no tanto el procedimiento como tal, sino el uso de CopyMemory.

Funciones “Virtual”.

VirtualAlloc

Api: Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long

VirtualLock

Api: Declare Function VirtualLock Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long) As Long

VirtualUnlock

Api: Declare Function VirtualUnlock Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long) As Long

VirtualFree

Api: Declare Function VirtualFree Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long

Estas funciones trabajan exactamente igual a sus homologas de arriba. Con la diferencia que trabajan sobre la memoria virtual.

<-- Capítulo VII

Regresar arriba

Regresar a la página principal

Capítulo IX -->

Desarrollado por Eduardo Roa. Copyright 2002-2003 Todos los derechos reservados