facturista.com - Foros de Factura Electrónica (Comprobante Fiscal Digital por Internet)

Venta de timbres y programas para Generar, Sellar y Timbrar Factura Electrónica (CFDI) en México
Fecha actual Jue Mar 28, 2024 4:18 am

Todos los horarios son UTC - 6 horas




Nuevo tema Responder al tema  [ 1 mensaje ] 
Autor Mensaje
NotaPublicado: Vie Nov 29, 2013 7:14 pm 
Desconectado

Registrado: Sab Mar 30, 2013 1:04 am
Mensajes: 47
Manejo de memoria, cadenas de caracteres devueltas

Cuando se transfieren enteros entre un lenguaje de programación y la DLL,
no existe problema alguno, no se requiere tratamiento especial.

El cuidado debemos tenerlo al enviar o recibir cadenas de caracteres,
dependiendo del lenguaje de programación, pueden requerirse algunas conversiones.

Generalmente, al enviar las cadenas a la DLL, pocos lenguajes requieren
un manejo explícito del programador.

En el caso de Delphi, se debe especificar que se envía como PChar.

libfacturista, no requiere que se le pasen cadenas por referencia
o cadenas con memoria asignada para ponerle datos dentro de la DLL.

Pero cuando se devuelven cadenas desde la DLL, algunos lenguajes
requieren tener memoria preasignada.

Muchos lenguajes crean su propia copia de la cadena devuelta y
liberan al programador de manejos posteriores.

libfacturista le proporciona una función que permite devolver
las cadenas de varias maneras:

Código:
int set_rsmm(string rsmm);


Esta función es para fijar la administracion de memoria de las cadenas devueltas
(returned string memory management) los valores del parámetro pueden ser:

"" : No hay asignacion de memoria, las cadenas devueltas pertenecen a la DLL
Este es el valor predeterminado y la mayoria de los entornos nativos funcionan bien asi,
ya que crean una copia de la cadena sin preocuparse de liberar la original

"c" : La cadena es asignada con malloc() y debe ser liberada por el cliente con free()

"bstr" : La cadena es asignada con SysAllocStringByteLen() y debe ser liberada por el cliente con SysFreeString()
VB 6 y .Net la liberan automaticamente,

"com" : La cadena es asignada con CoTaskMemAlloc() y debe ser liberada por el cliente con CoTaskMemFree()

En VB 6 es IMPORTANTE llamar esta funcion con "bstr" antes de usar las demas funciones de la dll, ej.
rsmm = set_rsmm("bstr")
Basta con llamarla una vez, En el ejemplo la llamamos en Form_Initialize() (inicializacion del formulario)

En C# o VBnet esta función es llamada dentro de la función de inicialización ( ansiApi.init() o utf16Api.init() )


Debemos tener en cuenta que de manera predeterminada, la memoria pertenece a la DLL y para los lenguajes que
en vez de sacar una copia usan el apuntador;
esa memoria sólo es válida mientras no se llame otra función de la DLL.

En Delphi, que recibe las cadenas como PChar (apuntador), si deseamos mantener esa cadena por más tiempo,
debemos copiarla:

Código:
suuid, serror: PChar;
...
suuid = StrNew( cfdi_uuid(h) );
serror = cfdi_error(h);
writeln(suuid);
writeln(serror);
StrDispose(suuid);

Si no hubiéramos llamado StrNew(), suuid se hubiera invalidado al usar cfdi_error() .

Al usar StrNew(), debemos llamar a StrDispose() al terminar de usar la cadena.


A partir de la versión 1.01.07, se proporciona una facilidad para que la memoria de la DLL
sea dinámica y siga siendo válida hasta que se libere explícitamente:

Código:
int set_gc(int enable);


Un parámetro mayor que 0 activa el recolector de memoria sin uso
Si está activado, las llamadas a cfdi_destruir(h) liberan la memoria de cadenas dinámicas asociadas a h
Para que obtengamos cadenas dinámicas, debemos llamar a set_rsmm(), esto no es necesario en general
ya que muchos lenguajes crean su copia de las cadenas devueltas por la DLL
No se debe activar el recolector si nuestro lenguaje se encarga de liberar la memoria, como es el caso de VB6

Usando el recolector de memoria, el código de Delphi quedaría así:

Código:
suuid, serror: PChar;
...
set_rsmm("c"); { las cadenas devueltas serán dinámicas }
set_gc(1); { activamos el recolector }

suuid = cfdi_uuid(h);
serror = cfdi_error(h);
writeln(suuid);
writeln(serror);
cfdi_destruir(h); { se liberan las cadenas dinámicas }


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 1 mensaje ] 

Todos los horarios son UTC - 6 horas


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 5 invitados


No puedes abrir nuevos temas en este Foro
No puedes responder a temas en este Foro
No puedes editar tus mensajes en este Foro
No puedes borrar tus mensajes en este Foro
No puedes enviar adjuntos en este Foro

Buscar:
Saltar a:  
cron
Powered by phpBB® Forum Software © phpBB Group
Traducción al Español Mexicano por nextgen en colaboración con phpbb-es.com