|
111
|
Programación / Programación C/C++ / Clases de almacenamiento
|
en: 26 Marzo 2013, 22:38 pm
|
Hola me decidí a crear un proyecto simple que trate de aplicar todas las keywords del lenguaje con respecto a las clases o directivas de almacenamiento. No creo haber utilizado todos los casos posibles, pero me parece que el resultado es un código que explica muy bien al menos como usar los casos más generales. Las keywords en cuestión son estas: extern static auto register inline mutable volatileNo me pregunten sobre 'mutable' y 'volatile' porque no las he usado nunca XD. El programa trata de mostrar información por pantalla para dejar en claro el lugar de almacenamiento de las variables utilizadas, y su valor de inicialización. También se deja en claro el uso de estas directivas en funciones. Otra cosa que quiero aclarar que 'extern' es por defecto, pero yo lo especifiqué explícitamente para esta demostración. Y también muestro una forma de usar una función que normalmente no se puede usar de un archivo fuente a otro, pero mediante su dirección se puede. Dejo el código. main.cpp// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// char* palabra[] = { "Hola", "Mi", "Nombre", "Es", "David", "Y", "El", "Tuyo?" }; char* msgList[] = { "HAHAHA", "HOHOHO", "HUHUHU", 0 }; char* cadenaCortada = "Hola\nMe\nDices\nTu\nNombre\n?\0"; //////////////////////////////////////////////////////////////////////////////////////////////// extern int variable1; extern int variable2 = 0; int variable3 = 0;// Es extern por defecto!, aunque no se especifique extern char cadena1[] = "AAAAAAAAAAAAAAA"; extern char cadena2[] = "AAAAAAAAAAAAAAA"; char cadena3[] = "BBBBBBBBBBBBBBB"; static int x; static int y = 0; //////////////////////////////////////////////////////////////////////////////////////////////// // MAL! (Revisar los conceptos de cada clase de almacenamiento) //auto int varmal1; //auto int varmal2=0; //register int varmal3; //register int varmal4=0; //////////////////////////////////////////////////////////////////////////////////////////////// //Mutable sólo puede ser aplicada a miembros de clases //Sirve para que determinados miembros de un objeto de una estructura o //clase declarado como constante, puedan ser modificados. //////////////////////////////////////////////////////////////////////////////////////////////// //Volatile se usa con objetos que pueden ser modificados desde el exterior del programa, //mediante procesos externos. //Es frecuente encontrar juntos los modificadores volatile y const: //si la variable se modifica por un proceso externo, no tiene mucho sentido que el //programa la modifique. volatile int varilo1; volatile int varilo2 = 0; volatile int ilvolo1 = 10; //int* p_ilvolo1 = &ilvolo1;// MAL! volatile int* p_ilvolo1 = &ilvolo1; //////////////////////////////////////////////////////////////////////////////////////////////// // HACK // El hack consiste en guardar las direcciones de las funciones 'static' y usar // punteros a función en las otras unidades de compilación. // De esa forma, el compilador no lo restringe. DWORD add_Func1_StringCompare = (DWORD)&Func1_StringCompare; DWORD add_Func2_StringLength = (DWORD)&Func2_StringLength; DWORD add_Func3_StripReturn = (DWORD)&Func3_StripReturn; //////////////////////////////////////////////////////////////////////////////////////////////// static int Func1_StringCompare(char* q, char* a) { do { if( *q!=*a ) return -1; if( !*q ) break; q++; a++; } while( *q ); return 0; } //////////////////////////////////////////////////////////////////////////////////////////////// static unsigned int Func2_StringLength(const char* f){ INT i=0; while(*f++) i++; return i; } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func3_StripReturn(char* str) { for(register unsigned int i=0;i<strlen(str);i++) if (str[i]==10 || str[i]==13) { str[i]=' '; } } //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// void inline Func4_MostrarCadenas1(){// Inline es sólo para funciones for(int i=0; i<(sizeof(palabra)/sizeof(palabra[0])); ++i) { printf("%d = %s\n", i, palabra[i]); } } //////////////////////////////////////////////////////////////////////////////////////////////// inline void Func5_MostrarMensajes1(){// Inline es sólo para funciones for(char** i = msgList; *i; i++) { MessageBox(0, *i, *i, 0); } } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Func6_getRAM(char* buf){ MEMORYSTATUS Status; ZeroMemory(&Status, sizeof(Status)); Status.dwLength = sizeof(Status); GlobalMemoryStatus(&Status); DWORD dwRAM = (DWORD)(Status.dwTotalPhys/(1024*1024)); wsprintf(buf, "%d MB", dwRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// void Func7_Variables1(){ // Valores de inicio y lugar de almacenamiento de las variables // putchar(10); int var1; int var2 = 0; static int var3; static int var4 = 0; volatile int var5; volatile int var6=0; printf("variable local sin inicializar: %d\n", var1); printf("variable local inicializada: %d\n", var2); printf("variable local static sin asignar: %d\n", var3); printf("variable local static asignada: %d\n", var4); printf("variable local volatile sin asignar: %d\n", var5); printf("variable local volatile asignada: %d\n", var6); // printf("variable global sin asignar: %d\n", variable1); printf("variable global asignada. %d\n", variable2); printf("variable global asignada: %d\n", variable3); printf("variable global static sin asignar: %d\n", x); printf("variable global static asignada: %d\n", y); printf("variable global volatile sin asignar: %d\n", varilo1); printf("variable global volatile asignada: %d\n", varilo2); printf("add variable local sin inicializar: 0x%X\n", &var1); printf("add variable local inicializada: 0x%X\n", &var2); printf("add variable local static sin asignar: 0x%X\n", &var3); printf("add variable local static asignada: 0x%X\n", &var4); printf("add variable local volatile sin asignar: 0x%X\n", &var5); printf("add variable local volatile asignada: 0x%X\n", &var6); // printf("add variable global sin asignar: 0x%X\n", &variable1); printf("add variable global asignada. 0x%X\n", &variable2); printf("add variable global asignada: 0x%X\n", &variable3); printf("add variable global static sin asignar: 0x%X\n", &x); printf("add variable global static asignada: 0x%X\n", &y); printf("add variable global volatile sin asignar: 0x%X\n", &varilo1); printf("add variable global volatile asignada: 0x%X\n", &varilo2); // El problema con la variable1 es que al haber usado 'extern' y no haberle // hecho una asignación de valor. el compilador entiende que se hace referencia // a una variable que está declarada en otra unidad de compilación. } //////////////////////////////////////////////////////////////////////////////////////////////// void Func8_Variables2(){ // Valores de inicio y lugar de almacenamiento de las variables // putchar(10); // Se crean y destruyen automáticamente (no se necesita especificar) auto int varbien1; auto int varbien2=0; // Si es posible, se van a almacenar en algún registro del CPU para tener // un acceso más rápido a ellas. (Tamaño adecuado para entrar en un registro!) register int varbien3; register int varbien4=0; printf("variable local auto sin asignar: %d\n", varbien1); printf("variable local auto asignada: %d\n", varbien2); printf("variable local register sin asignar: %d\n", varbien3); printf("variable local register asignada: %d\n", varbien4); auto int var1 = 85; auto int var2 = var1; printf("var1: %d add: 0x%X\n", var1, &var1); printf("var2: %d add: 0x%X\n", var2, &var2); register int var3 = 85; // Si estubiera en un registro no se obtendría una dirección de memoria! printf("var3: %d add: 0x%X\n", var3, &var3); register int i; // register int i=0; for(i=1; i<=10; i++){ if(i==1) printf("add i: 0x%X\n",&i); printf("%d",i); } putchar(10); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func9_dummy1(register int* x){ printf("x: %d add: 0x%X\n", *x, &x); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func10_dummy2(register int y){ printf("y: %d add: 0x%X\n", y, &y); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func11_dummy3(volatile int z){ printf("z: %d add: 0x%X\n", z, &z); } //////////////////////////////////////////////////////////////////////////////////////////////// // Retorna un INT volatile, sólo se aplica al tipo de retorno. volatile int Func12_dummy4(int arg){ int res = arg; return res; } //////////////////////////////////////////////////////////////////////////////////////////////// void Func13_Argumentos(){ putchar(10); int a = 500; Func9_dummy1(&a); int b = 1000; Func10_dummy2(b); int c = 5000; Func10_dummy2(c); int d = 100000; Func11_dummy3(d); int e = Func12_dummy4(15); printf("%d\n", e); } //////////////////////////////////////////////////////////////////////////////////////////////// int main(){ Func4_MostrarCadenas1(); Func5_MostrarMensajes1(); // Cualquiera de las 2 formas (con o sin extern, es lo mismo) extern void Test1_UnidadDeCompilacion1(); extern void Test2_UnidadDeCompilacion1(); extern void Test3_UnidadDeCompilacion1(); extern void Test1_UnidadDeCompilacion2(); extern void Test2_UnidadDeCompilacion2(); void Test3_UnidadDeCompilacion2(); Test1_UnidadDeCompilacion1(); Test2_UnidadDeCompilacion1(); Test3_UnidadDeCompilacion1(); Test1_UnidadDeCompilacion2(); Test2_UnidadDeCompilacion2(); Test3_UnidadDeCompilacion2(); Func8_Variables2(); Func3_StripReturn(cadenaCortada); printf("%s\n",cadenaCortada); system("pause"); return (0); }
unidad_comp1.cpp// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// int (*Ptr_Func1_StringCompare)(char*, char*); //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test1_UnidadDeCompilacion1(){ // Los externs en este caso son locales a esta función. extern void Func6_getRAM(char* buf); char TotalRAM[256] = ""; Func6_getRAM(TotalRAM); putchar(10); printf("Test1_UnidadDeCompilacion1: Total RAM: %s\n", TotalRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test2_UnidadDeCompilacion1(){ // Los externs en este caso son locales a esta función. extern DWORD add_Func1_StringCompare; extern char cadena1[]; extern char cadena2[]; extern char cadena3[]; putchar(10); Ptr_Func1_StringCompare = (int(*)(char*, char*))add_Func1_StringCompare; //if(Func1_StringCompare(cadena1, cadena2) == 0)// No se puede! if(Ptr_Func1_StringCompare(cadena1, cadena2) == 0) { printf("Test2_UnidadDeCompilacion1: IGUALES\n"); } // No se puede! porque getRam no es un extern "global" en esta unidad de compilación. //char TotalRAM[256] = ""; //Func6_getRAM(TotalRAM); //printf("Total RAM: %s\n", TotalRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test3_UnidadDeCompilacion1(){ // Cualquiera de las 2 formas extern void Func7_Variables1(); void Func7_Variables1(); Func7_Variables1(); }
unidad_comp2.cpp// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// // Los externs pueden ser globales para que sirvan en toda esta unidad de compilación unsigned int (*Ptr_Func2_StringLength)(const char*); extern DWORD add_Func2_StringLength; extern char cadena1[]; extern char cadena2[]; extern char cadena3[]; // Cualquiera de las 2 formas extern void Func13_Argumentos(); void Func13_Argumentos(); //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test1_UnidadDeCompilacion2(){ putchar(10); //int len1 = Func2_StringLength(cadena1);// No se puede! Ptr_Func2_StringLength = (unsigned int(*)(const char*))add_Func2_StringLength; int len1 = Ptr_Func2_StringLength(cadena1); printf("Test1_UnidadDeCompilacion2: len1: %d\n", len1); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test2_UnidadDeCompilacion2(){ // No se puede! Son 'inline' en otra unidad de compilación //Func4_MostrarCadenas1(); //Func5_MostrarMensajes1(); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test3_UnidadDeCompilacion2(){ Func13_Argumentos(); }
inclusiones.h// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #pragma once //////////////////////////////////////////////////////////////////////////////////////////////// // En el archivo de inclusión no se especifica la clase de almacenamiento. int Func1_StringCompare(char* q, char* a); unsigned int Func2_StringLength(const char* f); void Func3_StripReturn(char* str); void inline Func4_MostrarCadenas1(); inline void Func5_MostrarMensajes1();
CODEhttp://www.mediafire.com/?mzuaz5zxtttazut
|
|
|
113
|
Programación / Programación C/C++ / Re: Ejecutar un bat... Al inicio de Windows
|
en: 26 Marzo 2013, 22:01 pm
|
haber yo sólamente hice una búsqueda.. http://stackoverflow.com/questions/1154701/batch-cmd-adding-files-to-startup-listhttp://superuser.com/questions/71190/running-bat-file-at-startup-as-administrator-in-windows-7http://www.microloft.co.uk/startup.htmhttp://www.tomshardware.com/forum/258456-45-autoloading-file-registry-startuphttp://news.softpedia.com/news/How-To-Add-an-Application-To-Startup-Using-The-Registry-43488.shtmly si te falta más código para trabajar con el registro te paso algunos códigos que tenía guardados. // want to edit key "HKEY_LOCAL_MACHINE\Software\company name\game name\settings\value" // to "1" (DWORD) void a(){ HKEY hkey; DWORD dwDisposition; //ask for write permission KEY_WRITE if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\company name\\game name\\settings"), 0, NULL, 0, KEY_WRITE, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS) { // etc.. } if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\company name\\game name\\settings"), 0, NULL, 0, 0, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS){ DWORD dwType, dwSize; dwType = REG_DWORD; dwSize = sizeof(DWORD); DWORD rofl = 1; // does not create anything RegSetValueEx(hkey, TEXT("value"), 0, dwType, (PBYTE)&rofl, dwSize); RegCloseKey(hkey); } } LONG SetRegValue(const wchar_t* path,const wchar_t *name,const wchar_t *value) { LONG status; HKEY hKey; status = RegOpenKeyEx(HKEY_CURRENT_USER, (const char *)path, 0, KEY_ALL_ACCESS, &hKey); if ( (status == ERROR_SUCCESS) && (hKey != NULL)) { status = RegSetValueEx( hKey, (const char *)name, 0, REG_SZ, (BYTE*)value, ((DWORD)wcslen(value)+1)*sizeof(wchar_t)); RegCloseKey(hKey); } return status; }
char cdkey[14] = ""; void getCDKey() { HKEY l_hKey; DWORD l_dwBufLen = 17; DWORD type = REG_SZ; DWORD l_ret = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Ltfxhook", 0,KEY_QUERY_VALUE, &l_hKey); if(l_ret!=ERROR_SUCCESS) { Con_Echo("&rltfxkey retreival failed"); } l_ret = RegQueryValueEx(l_hKey,"Key",NULL,&type,(LPBYTE)&cdkey,&l_dwBufLen); }
char cdkey[14] = ""; void getCDKey() { HKEY l_hKey; DWORD l_dwBufLen = 14; DWORD type = REG_SZ; DWORD l_ret = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Valve\\CounterStrike\\Settings", 0,KEY_QUERY_VALUE, &l_hKey); if(l_ret!=ERROR_SUCCESS) { DWORD l_ret = RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Valve\\Half-life\\Settings", 0,KEY_QUERY_VALUE, &l_hKey); if(l_ret!=ERROR_SUCCESS) return; } l_ret = RegQueryValueEx(l_hKey,"Key",NULL,&type,(LPBYTE)&cdkey,&l_dwBufLen); for(int i=0;i<13;i++) { switch( cdkey[i] ) { case '0': cdkey[i] = 'g'; break; case '1': cdkey[i] = 'a'; break; case '2': cdkey[i] = 'u'; break; case '3': cdkey[i] = 'l'; break; case '4': cdkey[i] = 'x'; break; case '5': cdkey[i] = 't'; break; case '6': cdkey[i] = 'c'; break; case '7': cdkey[i] = 'm'; break; case '8': cdkey[i] = 'r'; break; case '9': cdkey[i] = 'j'; break; } } }
void printerr(DWORD dwerror) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwerror, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Process any inserts in lpMsgBuf. // ... // Display the string. if (isOut) { fprintf(fout, "%s\n", lpMsgBuf); } else { printf("%s\n", lpMsgBuf); } // Free the buffer. LocalFree(lpMsgBuf); } bool regreadSZ(string& hkey, string& subkey, string& value, string& returnvalue, string& regValueType) { char s[128000]; map<string,HKEY> keys; keys["HKEY_CLASSES_ROOT"]=HKEY_CLASSES_ROOT; keys["HKEY_CURRENT_CONFIG"]=HKEY_CURRENT_CONFIG; //DID NOT SURVIVE? keys["HKEY_CURRENT_USER"]=HKEY_CURRENT_USER; keys["HKEY_LOCAL_MACHINE"]=HKEY_LOCAL_MACHINE; keys["HKEY_USERS"]=HKEY_USERS; HKEY mykey; map<string,DWORD> valuetypes; valuetypes["REG_SZ"]=REG_SZ; valuetypes["REG_EXPAND_SZ"]=REG_EXPAND_SZ; valuetypes["REG_MULTI_SZ"]=REG_MULTI_SZ; //probably can't use this. LONG retval=RegOpenKeyEx( keys[hkey], // handle to open key subkey.c_str(), // subkey name 0, // reserved KEY_READ, // security access mask &mykey // handle to open key ); if (ERROR_SUCCESS != retval) {printerr(retval); return false;} DWORD slen=128000; DWORD valuetype = valuetypes[regValueType]; retval=RegQueryValueEx( mykey, // handle to key value.c_str(), // value name NULL, // reserved (LPDWORD) &valuetype, // type buffer (LPBYTE)s, // data buffer (LPDWORD) &slen // size of data buffer ); switch(retval) { case ERROR_SUCCESS: //if (isOut) { // fprintf(fout,"RegQueryValueEx():ERROR_SUCCESS:succeeded.\n"); //} else { // printf("RegQueryValueEx():ERROR_SUCCESS:succeeded.\n"); //} break; case ERROR_MORE_DATA: //what do I do now? data buffer is too small. if (isOut) { fprintf(fout,"RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n"); } else { printf("RegQueryValueEx():ERROR_MORE_DATA: need bigger buffer.\n"); } return false; case ERROR_FILE_NOT_FOUND: if (isOut) { fprintf(fout,"RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n"); } else { printf("RegQueryValueEx():ERROR_FILE_NOT_FOUND: registry value does not exist.\n"); } return false; default: if (isOut) { fprintf(fout,"RegQueryValueEx():unknown error type 0x%lx.\n", retval); } else { printf("RegQueryValueEx():unknown error type 0x%lx.\n", retval); } return false; } retval=RegCloseKey(mykey); if (ERROR_SUCCESS != retval) {printerr(retval); return false;} returnvalue = s; return true; }
HKEY hKey; LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Perl", 0, KEY_READ, &hKey); bool bExistsAndSuccess (lRes == ERROR_SUCCESS); bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND); std::wstring strValueOfBinDir; std::wstring strKeyDefaultValue; GetStringRegKey(hKey, L"BinDir", strValueOfBinDir, L"bad"); GetStringRegKey(hKey, L"", strKeyDefaultValue, L"bad"); LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) { nValue = nDefaultValue; DWORD dwBufferSize(sizeof(DWORD)); DWORD nResult(0); LONG nError = ::RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, reinterpret_cast<LPBYTE>(&nResult), &dwBufferSize); if (ERROR_SUCCESS == nError) { nValue = nResult; } return nError; } LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue) { DWORD nDefValue((bDefaultValue) ? 1 : 0); DWORD nResult(nDefValue); LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue); if (ERROR_SUCCESS == nError) { bValue = (nResult != 0) ? true : false; } return nError; } LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) { strValue = strDefaultValue; WCHAR szBuffer[512]; DWORD dwBufferSize = sizeof(szBuffer); ULONG nError; nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize); if (ERROR_SUCCESS == nError) { strValue = szBuffer; } return nError; }
XD
|
|
|
114
|
Programación / Programación C/C++ / Re: Problema con struct
|
en: 26 Marzo 2013, 21:56 pm
|
a veces no da error mientras no modifiques algo crítico, es decir si te salís fuera del límite de una cadena y escribís otra, en teoría no pasa nada. Pero si al pasarte fuera, terminás modificando la dirección almacenada de un puntero por ejemplo, entonces si sería una modificación crítica.
array[2] en teoría debería guardar 2 elementos que son array[0] y array[1], si usás [2] sería el tercero. aunque si no tira error debés estar modificando el dato que se encuentra a continuación, o a no ser que el compilador sea inteligente como para haber creado un array de 3.
|
|
|
115
|
Programación / Programación C/C++ / Re: Ayuda en Código de Snake
|
en: 26 Marzo 2013, 21:30 pm
|
XD a secas
eso significa que intenta comprobar si tiene un valor distinto de 0, una comprobación de estado booleano. Pero si nunca es 0 entonces no tiene sentido comprobarlo.
a veces es muy útil por ejemplo para comprobar si un puntero fue asignado con una dirección de memoria.
int* pun = 0;//Asignar
if(pun){ }
|
|
|
116
|
Programación / Programación C/C++ / CRT personalizada
|
en: 26 Marzo 2013, 16:21 pm
|
Hola, estaba leyendo este texto: 5) make your own CRT
MUCH easier than you might think... what do you need from a runtime? to allocate/deallocate mem? to print to the console?
look up the functions required to allocate memory from windows...
now just have some functions that set needed globals:
HANDLE g_hHeap = 0;
extern "C" BOOL crt_initialize() { return (g_hHeap = HeapCreate(0, 0, 0))); } extern "C" BOOL crt_uninitialize() { return HeapDestroy(g_hHeap)); }
you can now, if you choose, override the default CRT entry's name:
extern "C" int mainCRTStartup() { crt_initialize(); // maybe get the arguments here with GetCommandLine() main();//maybe send args here return 0; }
so how do you do malloc()/free() ? how do you do new/delete? it's as simple as passing the requested sizes to the OS functions along with the heap handle made during the initialization
extern "C" void * malloc(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); } extern "C" void free(void * p) { HeapFree(g_hHeap, 0, p); }
void * __cdecl operator new(unsigned int size) { return HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, size); } void __cdecl operator delete(void *p) { HeapFree(g_hHeap, 0, p); }
hopefully you can figure out the rest... especially how your crt entry should acquire and supply needed parameters to your main() or winmain()
6) bypass the normal CRT
if you don't want to write a CRT, but also don't want the cruft that comes with the normal CRT, just specify that the linker should jump to your code first, NOT the crt
/ENTRY:yourfunction
Y buscando información encontré algunas cosas interesantes, por ejemplo 2 proyectos de CRT propias, más que el otro estuve mirando el más reciente del 2010, que se llama 'minicrt'. Me parece que les puede interesar a algunos, porque en el proyecto se puede encontrar el código de muchas implementaciones de funciones de C. http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e6f222d7-8e20-4d4a-8a6f-b72ade3661ac/http://www.benshoof.org/blog/minicrt/http://www.wheaty.net/http://www.benshoof.org/blog/archive/http://www.wheaty.net/downloads.htmSe pueden encontrar versiones de las funciones originales que cumplen con los standards de C, hay implementaciones de algunas funciones que a mi por ejemplo me interesaban crear implementaciones personalizadas de ellas, atoi, strtok, y muchas otras por ejemplo atoi //========================================== // minicrt - Chris Benshoof 2009 // atoi(), modified from // http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/atoi.c.htm //========================================== #include "libctiny.h" extern "C" int __cdecl atoi(const char *String) { int Value = 0, Digit; int c; while ((c = *String++) != '\0') { if (c >= '0' && c <= '9') Digit = (c - '0'); else break; Value = (Value * 10) + Digit; } return Value; }
aparte es un proyecto no tan antiguo, dice que es del 2010. El otro si es del 2000. saludos
|
|
|
118
|
Programación / Programación C/C++ / Re: Dudas Punteros
|
en: 26 Marzo 2013, 14:26 pm
|
por ejemplo, veamos esto http://www.zator.com/Cpp/E2_2a.htmLas variables pueden ser de diferentes tipos de datos, los punteros son variables pero de tipo puntero en sí, independientemente si fueron declaradas como CHAR, INT, etc. Con referencia a las variables de tipo puntero, es tal como te dijeron. Algo que también está permitido es hacer typecasting de variables normales para poder usarlas como punteros. Algo que yo llamo un "pseudopuntero" pero es tan sólo el uso del typecasting. por ejemplo: int entero1=5; DWORD pseudopuntero = (DWORD)&entero1; printf("entero1 %X\n", &entero1); printf("pseudopuntero %X\n", pseudopuntero); printf("pseudopuntero %d\n", *(int*)pseudopuntero); system("pause");
Nótese que para un "pseudopuntero" se requiere tener en cuenta el tipo de dato correcto para guardar una dirección de memoria, y el tipo correcto de dato para mostrar el valor de la variable. Es algo mucho más complicado por eso se prefiere usar variables de tipo puntero directamente, las cuales son las correctas para todo esto. Cualquier cosa se puede ver otro ejemplo http://foro.elhacker.net/programacion_cc/pseudopunteros-t385862.0.html
|
|
|
119
|
Programación / .NET (C#, VB.NET, ASP) / Steam_RCP: GUI parecida al Steam y conexión con BDD
|
en: 24 Marzo 2013, 18:30 pm
|
Hola quería publicar el código fuente de un proyecto que había empezado a principios del año pasado (2012) y que presenté a modo de proyecto, en mi curso de programación .NET que estaba haciendo ese año. El archivo Acerca.txtSteam_RCP es un programa con interfáz gráfica que trata de parecerse a la de la plataforma 'Steam'.
Se conecta a una base de datos SQL Server y permite realizar operaciones con la base de datos.
Se trata de un sistema simple de gestión. Fue hecho con fines educativos a modo de un proyecto de estudiantes de programación .NET , a principios del 2012.
La idea de publicarlo es para aquellos que intenten hacer algo parecido puedan usar este proyecto como una base.
Las funcionalidades de una interfáz se emularon en lo posible de las mismas de Windows, ya que se anularon algunas del sistema para recrearlas desde el programa.
Esta publicación no incluye el código SQL para la creación de la base de datos, y no incluye el diagrama DER de la base de datos.
Lo que se incluye es el código fuente completo de la aplicación, el código fuente de un instalador, y los archivos de instalación.
Atte. 85
Me parece que puede ser de utilidad para personas que tengan que hacer proyectos similares, con conexión a base de datos SQL Server. En la descarga se incluyen las cosas que dice en el archivo Acerca.txt. En cuanto a la GUI, aparte de que tiene un parecido con la interfáz gráfica de la plataforma Steam, en realidad está copiada de la interfaz que tiene la aplicación de un amigo que también es usuario de este foro. Él había creado una excelente aplicación con GUI en C++, y ami me había gustado su diseño por lo que lo implementé en este programa, obviamente desde C#. Acerca del programa, es como había dicho, un programa que realiza operaciones sobre una base de datos SQL Server. http://img837.imageshack.us/img837/6297/steamrcp2.pnghttp://img163.imageshack.us/img163/2473/steamrcp3.pngSi quieren hacerlo arrancar directamente hacía el panel principal sin intentar cargar la base de datos, van a tener que comentar una parte del código dentro de : private void Form1_Load(object sender, EventArgs e) { ...
PROYECTO MSVC# 2010http://www.mediafire.com/?uohce8xfi568fkw
|
|
|
|
|
|
|