|
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mensajes - Eternal Idol
Páginas: 1 ... 197 198 [199] 200 201 ... 205
4951
« en: Sábado 3 de Julio de 2004, 11:51 »
No tengo ni idea de los programas de los que hablas pero si lo vas a hacer en Visual C++ supongo que será para Windows y en eso si te puedo ayudar. Te recomiendo que leas todo el About y Using. http://msdn.microsoft.com/library/en-us/de...s_resources.aspLas funciones de configuración son G/SetCommState (estas dos me parece que son las que te sirven para configurar "8 bits de datos, 1 bit de parada, paridad:none, 9600 baudios en baudrate y Xon/Xonff como control de flujo??") y también estan G/SetCommTimeouts para manejar el tiempo que esperan las operaciones de lectura y escritura.
4952
« en: Sábado 3 de Julio de 2004, 11:43 »
Primero que nada el edit es multiline, verdad? Se me ocurren dos métodos, una simple y el otro bastante complejo: 1) Buscar todas los punto y coma del texto y agregarles el \n 2)Crear un edit propio que lo haga
4953
« en: Sábado 3 de Julio de 2004, 11:39 »
Faith No More esa una banda yankee excepcional (inclasificable), las otras son todas bandas argentinas de Heavy Metal.
4954
« en: Sábado 3 de Julio de 2004, 11:36 »
Grecia también, se lo merecen y no van a tener una oportunidad así nunca más, se van a matar por ganar la copa. Felicitaciones a Grecia de cualquier manera!
4955
« en: Sábado 3 de Julio de 2004, 11:31 »
4956
« en: Viernes 2 de Julio de 2004, 08:45 »
para win 98 En esa misma frase.
4957
« en: Jueves 1 de Julio de 2004, 10:58 »
Crear nuestra propia Run Time Library (Tercera Parte) En la MSDN encontré algo interesante sobre la opción /ENTRY del linker: "Type a function name in the Entry-Point Symbol text box (or in the function argument on the command line). The function must be defined with the __stdcall calling convention. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .EXE file) or DllEntryPoint (for a DLL). It is recommended that you let the linker set the entry point so that the C run-time library is initialized correctly, and C++ constructors for static objects are executed."Vamos a probar un poco de código con objetos estáticos: ESTATICOS.CPP #include <windows.h> void SayLong(int number) { char Data[10]; ltoa(number,Data,10); MessageBox(0,Data,"El Numero",0); } class Man { public: Man() { SayLong(66); } ~Man() { SayLong(99); } }; Man Jacinto; Man Pedrito; void main() { }
Compilando y linkeando este código con la Run Time Library por defecto conseguimos cuatro MessageBox, dos con 66 (el constructor) y dos con 99 (el destructor). Ahora tratamos de compilar y linkear con nuestra Run Time Library y nos encontramos con lo siguiente: estaticos.obj : error LNK2001: unresolved external symbol _atexit estaticos.exe : fatal error LNK1120: 1 unresolved externalsSi vamos a la MSDN podemos ver que lo que hace esta función es ejecutar la función que le es pasada como parametro al final del programa. Usando una estructura de pila (LIFO). Entonces que nos detiene? Que nos imposibilita crear una función simple como esa? Nada, manos a la obra señores. C_ATEXIT.CPP #include <malloc.h> unsigned long *Funcs = 0; int n_funcs = 0; extern "C" int atexit(void (__cdecl *func)(void)) { if (!Funcs) { Funcs = (unsigned long*)malloc(1); } Funcs = (unsigned long*)realloc(Funcs,(n_funcs+1)*4); Funcs[n_funcs] = (unsigned long)func; n_funcs++; return 0; } extern "C" void destructores() { for (int x = n_funcs-1;x >= 0;x--) { void (__cdecl *calla)(void) = (void (__cdecl *)(void))Funcs[x]; calla(); } free(Funcs); }
Hermoso el código verdad? Cada vez que se llama a la función atexit() se comprueba si ya tiene valor la estructura donde vamos a guardar los punteros a las funciones. Se realloca la memoria necesaria y se le asigna al elemento actual el parametro func. Siempre devolvemos cero que indica que no hubo ningún error. Pero este código hermoso que hace exactamente hasta ahora? Ir llenando una lista de punteros a funciones, perfecto pero nos falta algo muy importante, recordemos que atexit() crea una lista de funciones que van a ser llamadas al final del programa. El principio del programa es la función de ENTRADA (solo nos interesan main, WinMain y DllMain ya que si fuera otra no usaría la Run Time Library, ni la nuestra ni la de VC++) que sabemos como se ejecuta, la llamamos nosotros desde nuestra Run Time Library por lo tanto sabemos perfectamente cuando termina de ejecutarse; en la siguiente instrucción a la llamada a main() el programa debe ejecutar la lista de funciones de atexit() y limpiar el buffer utilizado. Estas dos cosas las hace la función destructores() que está también en C_ATEXIT.CPP. Ahora mismo podríamos compilar el programa ESTATICOS.CPP pero no pasaría nada, la compilación y el linkeo serían satisfactorios pero nuestro programa no haría absolutamente nada. La pregunta del millón, quien llama a la función atexit(): la propia Run Time Library la llama. Acertaron? No me mientan eh. Y cuando y porque la llama? Porque el compilador le pasa el puntero del destructor al ejecutar el constructor, por lo tanto, al no tener implementado nuestro código para manejar los constructores estáticos no recibimos ninguna llamada a atexit() y destructores() se ejecuta sin ningún puntero al que llamar. Que hace el compilador para decirnos que existen constructores de objetos estáticos? El compilador crea un función diferente para cada uno de los objetos estáticos (esto lo podemos comprobar viendo las direcciones que le pasa por cada objeto a atexit) y nos pasa dentro del ejecutable las 'etiquetas' (posición en el archivo) de esas funciones a ejecutarse. data_seg #pragma data_seg( ["section-name"[, "section-class"] ] )
Specifies the default section for data. For example:
#pragma data_seg( "MY_DATA" )
causes data allocated following the #pragma statement to be placed in a section called MY_DATA.
Data allocated using the data_seg pragma does not retain any information about its location.
Estas secciones que se definen con #pragma data_seg son escritas por el linker dentro del ejecutable y tienen punteros, a inicializadores de C, constructores de C++, pre-terminadores de C y terminadores de C que forman tablas, estas se guardan en variables que tienen el comienzo y el fin de la tabla y son pasadas a una función llamada _initterm() que se encarga de llamar a todos esos punteros ejecutando su código. Esta es la forma en la que se llama a al constructor de de un objeto estático. Nuestro nuevo C_MAIN.CPP: #include <malloc.h> #include <string.h> extern "C" int __argc = 1; extern "C" char** __argv = 0; extern "C" void __stdcall ExitProcess(unsigned long uExitCode); extern "C" char* __stdcall GetCommandLineA(void); extern int main(int argc, char *argv[],char *env[]); extern "C" int __stdcall MessageBoxA(int a,char *b,char *c,unsigned int p); typedef void (__cdecl *_PVFV)(void); #pragma data_seg(".CRT$XIA") _PVFV __xi_a[] = { 0 }; #pragma data_seg(".CRT$XIZ") _PVFV __xi_z[] = { 0 }; #pragma data_seg(".CRT$XCA") _PVFV __xc_a[] = { 0 }; #pragma data_seg(".CRT$XCZ") _PVFV __xc_z[] = { 0 }; typedef void (* PFV)(void); #pragma data_seg(".CRT$XPA") PFV __xp_a = 0; /* C pre-terminators */ #pragma data_seg(".CRT$XPZ") PFV __xp_z = 0; #pragma data_seg(".CRT$XTA") PFV __xt_a = 0; /* C terminators */ #pragma data_seg(".CRT$XTZ") PFV __xt_z = 0; extern "C" void __cdecl _initterm(_PVFV *, _PVFV *); //__xi_a[], __xi_z[]; /* C initializers */ //__xc_a[], __xc_z[]; /* C++ initializers */ //__xp_a[], __xp_z[]; /* C pre-terminators */ //__xt_a[], __xt_z[]; /* C terminators */ extern "C" void destructores(); #define FALSE 0 #define TRUE 1 extern "C" void mainCRTStartup() { char *parametros = GetCommandLineA(); char *temp = (char*)malloc(2048); memset(temp,0,2048); __argc = 0; __argv = (char**)malloc(4); char Except = FALSE; while(*parametros) { if (*parametros == 34) { if (Except == FALSE) { Except = TRUE; } else { Except = FALSE; if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } } parametros++; continue; } if ( (*parametros == 32) && (Except == FALSE) ) { if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } } else { unsigned long pos = strlen(temp); temp[pos] = *parametros; temp[pos+1] = 0; } parametros++; } if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } free(temp); _initterm(__xi_a,__xi_z); _initterm(__xc_a,__xc_z); main(__argc,__argv,0); _initterm(&__xp_a,&__xp_z); _initterm(&__xt_a,&__xt_z); destructores(); for (int y = 0;y < __argc;y++) { free(__argv[y]); } free(__argv); ExitProcess(0); } static void __cdecl _initterm(_PVFV *pfbegin,_PVFV *pfend) { while (pfbegin < pfend) { if (*pfbegin) { (**pfbegin)(); } ++pfbegin; } }
Este nuevo main define las diferentes secciones donde se encontraran las benditas tablas, llama a las tablas de inicio justo antes que a main() y a las de terminaciones justo después, además de llamar a nuestra función destructores(). Las tablas son procesadas por la función initterm() que recorre la tablae de punteros a funciones, ejecutando cada uno de ellas, hasta encontrar un puntero nulo. Creamos nuestra libreria y ESTATICOS.EXE: cl /c *.cpp lib *.obj /out:clib.lib cl /c ESTATICOS.CPP link ESTATICOS.OBJ /NODEFAULTLIB USER32.LIB KERNEL32.LIB CLIBCLIB.LIB
Ahora si, tenemos el mismo comportamiento que con la Run Time Library de VC++ para los objetos estáticos. Un regalito en esta parte, vamos a ver como manejar las variables de entorno: C_MAIN.CPP #include <malloc.h> #include <string.h> //entorno extern "C" int vars = 0; extern "C" char** _environ = 0; extern "C" char* __stdcall GetEnvironmentStrings(void); extern "C" bool __stdcall FreeEnvironmentStringsA(char *block); void __cdecl _envinit(void); //parametros extern "C" int __argc = 1; extern "C" char** __argv = 0; extern "C" void __stdcall ExitProcess(unsigned long uExitCode); extern "C" char* __stdcall GetCommandLineA(void); extern int main(int argc, char *argv[],char *env[]); extern "C" int __stdcall MessageBoxA(int a,char *b,char *c,unsigned int p); typedef void (__cdecl *_PVFV)(void); #pragma data_seg(".CRT$XIA") _PVFV __xi_a[] = { 0 }; #pragma data_seg(".CRT$XIZ") _PVFV __xi_z[] = { 0 }; #pragma data_seg(".CRT$XCA") _PVFV __xc_a[] = { 0 }; #pragma data_seg(".CRT$XCZ") _PVFV __xc_z[] = { 0 }; typedef void (* PFV)(void); #pragma data_seg(".CRT$XPA") PFV __xp_a = 0; /* C pre-terminators */ #pragma data_seg(".CRT$XPZ") PFV __xp_z = 0; #pragma data_seg(".CRT$XTA") PFV __xt_a = 0; /* C terminators */ #pragma data_seg(".CRT$XTZ") PFV __xt_z = 0; extern "C" void __cdecl _initterm(_PVFV *, _PVFV *); //__xi_a[], __xi_z[]; /* C initializers */ //__xc_a[], __xc_z[]; /* C++ initializers */ //__xp_a[], __xp_z[]; /* C pre-terminators */ //__xt_a[], __xt_z[]; /* C terminators */ extern "C" void destructores(); #define FALSE 0 #define TRUE 1 extern "C" void mainCRTStartup() { char *parametros = GetCommandLineA(); char *temp = (char*)malloc(2048); memset(temp,0,2048); __argc = 0; __argv = (char**)malloc(4); char Except = FALSE; while(*parametros) { if (*parametros == 34) { if (Except == FALSE) { Except = TRUE; } else { Except = FALSE; if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } } parametros++; continue; } if ( (*parametros == 32) && (Except == FALSE) ) { if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } } else { unsigned long pos = strlen(temp); temp[pos] = *parametros; temp[pos+1] = 0; } parametros++; } if (strlen(temp) > 0) { __argv = (char**)realloc(__argv,4 * (__argc+1)); __argv[__argc] = (char*)malloc(strlen(temp) + 1); memset(__argv[__argc],0,strlen(temp) + 1); strcpy(__argv[__argc],temp); strcpy(temp,""); __argc++; } free(temp); _initterm(__xi_a,__xi_z); _initterm(__xc_a,__xc_z); _envinit(); main(__argc,__argv,_environ); _initterm(&__xp_a,&__xp_z); _initterm(&__xt_a,&__xt_z); destructores(); for (int y = 0;y < __argc;y++) { free(__argv[y]); } free(__argv); for (int z = 0;z < vars;z++) { if (_environ[z]) { free(_environ[z]); } } free(_environ); ExitProcess(0); } static void __cdecl _initterm(_PVFV *pfbegin,_PVFV *pfend) { while (pfbegin < pfend) { if (*pfbegin) { (**pfbegin)(); } ++pfbegin; } } void __cdecl _envinit(void) { char *var = GetEnvironmentStrings(); _environ = (char**)malloc(4); while(*var) { _environ = (char**)realloc(_environ,(vars + 1) * 4); _environ[vars] = (char*)malloc(strlen(var) + 1); memset(_environ[vars],0,strlen(var) + 1); strcpy(_environ[vars],var); (char*)var += strlen((char*)var); (char*)var +=1; vars++; } FreeEnvironmentStringsA(var); }
Esta nueva versión del C_MAIN.CPP incorpora la función _envinit, que cre la lista de variables de entorno y le pasa la variable _environ a la función main() de nuestro programa. Ahora vamos a implementar getenv y putenv: C_PUTENV.CPP #include <malloc.h> #include <string.h> extern "C" int vars; extern "C" char** _environ; bool compararPut(char *s1,const char *s2) { while(*s2) { if (*s1 != *s2) { return false; } s1++; s2++; } return true; } extern "C" int putenv(const char *envstring) { for (int x = 0;x < vars;x++) { if (!_environ[x]) { continue; } if (compararPut(_environ[x],envstring) == true) { char *ptr = (char*)envstring; while(*envstring) { if ( (*ptr == '=') && (*++ptr == 0) ) { free(_environ[x]); _environ[x] = 0; return 0; } ptr++; } strcpy(_environ[x],envstring); return 0; } } _environ = (char**)realloc(_environ,(vars + 1) * 4); _environ[vars] = (char*)malloc(strlen(envstring) + 1); memset(_environ[vars],0,strlen(envstring) + 1); strcpy(_environ[vars],envstring); vars++; return 0; }
C_GETENV.CPP #include <string.h> extern "C" int vars; extern "C" char** _environ; bool compararGet(char *s1,const char *s2) { while(*s2) { if (*s1 != *s2) { return false; } s1++; s2++; } if (*s1 == '=') { return true; } return false; } extern "C" char *getenv(const char *varname) { for (int x = 0;x < vars;x++) { if (!_environ[x]) { continue; } if (compararGet(_environ[x],varname) == true) { return (_environ[x]+strlen(varname)+1); } } return 0; }
Podemos probar su correcto funcionamiento con cualquier programa que use el parametro envp o simplemente cambiando variables del entorno como TMP (el path de los archivos temporales). En la cuarta parte veremos como implementar las funciones de entrada y salida por consola. Saludos, Mariano. Autor: Mariano Ventaja http://www.c0d3rz.com.arDescarga: http://c0d3rz.com.ar/foro/viewtopic.php?t=104
4958
« en: Jueves 1 de Julio de 2004, 10:48 »
Me parece que esto no es una oferta de empleo sino un ofrecimiento de un servicio. Por lo menos así lo veo yo.
4959
« en: Jueves 1 de Julio de 2004, 10:47 »
Para que lo queres hacer? Osea, no vas a obtener ninguna mejora de la calidad de la imagen ... me parece que no podes inferir 255 colores a partir de 2. Según tengo entendido esto se hace con imagenes en colores para pasarlas a blanco y negro.
4960
« en: Jueves 1 de Julio de 2004, 10:44 »
Programaste para Windows alguna vez en ensamblador? Porque me parece que eso no es código de 32 bits ...
4961
« en: Miércoles 30 de Junio de 2004, 17:00 »
Pero con ese código las palabras solo las mostras en pantalla, deberías ponerlas en un array para poder ordenarlas.
4962
« en: Miércoles 30 de Junio de 2004, 16:55 »
Todo bien La verdad no, no escuché nunca a Darude. Puse que me gusta a mi en un post anterior: Black Sabbath AC/DC Megadeth Faith No More Almafuerte Logos Hermética V8 Por cierto Eternal Idol además de ser un álbum de Black Sabbath es una escultura de Auguste Rodin
4963
« en: Martes 29 de Junio de 2004, 20:59 »
4964
« en: Martes 29 de Junio de 2004, 19:51 »
Lo que intenta hacer el programa esa cambiar el color de la letra y el fondo del programa block de notas? (notepad.exe)
4965
« en: Martes 29 de Junio de 2004, 19:39 »
La verdad no te comprendo totalmente, a ver si es así lo que queres hacer: una aplicación para Windows que tiene dos menues, (por ejemplo File y Edit). En File tiene que ser por ejemplo de color rojo la letra, la que diga File, Open, Save, etc; y en Edit el fondo tiene que ser de color verde todos los menues. Es así??
4966
« en: Martes 29 de Junio de 2004, 18:55 »
Estamos hablando de una aplicación de consola o de una de ventanas? De cualquiera de las dos maneras, siendo para Windows tenes que usar la API.
4967
« en: Martes 29 de Junio de 2004, 18:02 »
Para que Sistema Operativo?
4968
« en: Martes 29 de Junio de 2004, 09:05 »
Si, divertite con Pascal yMS-DOS son un lenguaje y un Sistema Operativo muy poderosos.
4969
« en: Lunes 28 de Junio de 2004, 19:55 »
Oye y que paso con la musica Trans o tecno ...?? Es que acaso eso es música? PD. Es SOLO una broma eh.
4970
« en: Lunes 28 de Junio de 2004, 19:54 »
Colores en donde? En consola? Para que Sistema Operativo?
4971
« en: Lunes 28 de Junio de 2004, 08:36 »
4972
« en: Domingo 27 de Junio de 2004, 22:42 »
El punto es que esa función es para una aplicación de modo consola y se usa en programas viejos hechos para MS-DOS. Si queres también podes crear tu gotoxy, usando las funciones de lectura y escritura de bajo nivel de consolas, fijate en la MSDN. http://msdn.microsoft.com/library/en-us/dl...pplications.asp
4973
« en: Domingo 27 de Junio de 2004, 16:01 »
4974
« en: Sábado 26 de Junio de 2004, 10:38 »
CreateFile está bien pero tener que configurar el puerto: "The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O. For more information about communications, see Communications." Leelo todo, te va a servir mucho, las funciones para configurar creo que eran G/SetCommConfig, G/SetCommState, G/SetCommTimeouts, http://msdn.microsoft.com/library/default....s_resources.aspAcá en casa no tengo el código fuente, pero el Lunes en el trabajo puedo ver mi programa para enviar faxes y te ayudo un poco más.
4975
« en: Viernes 25 de Junio de 2004, 17:48 »
No hay problema cada uno puede pensar lo que quiera, pero para mi el que no conoce a Jim Morrison vive en un tupper o lo acaban de descongelar después de cien años ...
Páginas: 1 ... 197 198 [199] 200 201 ... 205
|
|
|