Ver la versión completa : programar en c++ y variables/direcciones del sistema
the_goulin
12/07/2005, 12:41
Hola,
pues eso un par de preguntillas
¿se puede compilar en c++ para la gp32 con el SDK Oficial? y si se puede como? algun ejemplillo/plantilla please
¿de donde puedo sacar las variables/direcciones de sistema de la gp? no encuentro ninguna pagina y veo que la gente los usa, por ejemplo en el Magical Noseque (no recuerdo el resto del nombre) que se libero el codigo fuente hace poco utiliza la dirección de memoria donde se almacena la paleta para crear efectos Fade in fade off ¿de donde ha sacado esa dirección?
hay gente que tiene la dirección de la variable del sistema que indica cuando se ha producido el refresco de la pantalla... y eso de donde lo han sacado? en algun lado estara documentado, vamos digo yo, no?
Pos solo eso, gracias
The_Goulin
No conozco nadie que haya conseguido compilar C++ con el SDK oficial con el compilador GCC (aunque oí algo hace muuuucho de que sí se podía).
Sí que se puede hacer con el ADS.
En cuanto a lo que preguntas de las direcciones, las sacan de la documentación del procesador.
Me parece que aquí, el la web de Mr.Spiv encontrarás bastante material: http://www.cs.helsinki.fi/u/jikorhon/condev/gp32/download.html#pdf
Oankali.
No conozco nadie que haya conseguido compilar C++ con el SDK oficial con el compilador GCC (aunque oí algo hace muuuucho de que sí se podía).
Sí que se puede hacer con el ADS.
Compilar se puede perfectamente ... yo hace muuucho compile alguna cosilla. Los rumores eran que se necesitaba algun parche porque la gestion de memoria (new y destruct) de objetos parecia que no tiraba bien y tendia a dejar memoria por ahi purulando.
Te pasaria el codigo pero no tengo idea de donde andaran las cosillas que hice en c++, lo que si te digo que fue con el minigp32 y el sdk oficial.
Aiken
mortimor
12/07/2005, 15:27
Creo que en las versiones mas actuales del GCC no hay problemas con "new".
Direccioens de registros pides??? mira en los ejemplos de MrSpiv y en los includes del Mirko's SDK.
No se si usare alguna caracteristica del c++ en mi codigo, pero clases, sobrecarga de operadres y esas cosas, no.
mortimor
12/07/2005, 16:04
Sera que estoy yo equivocado :), ahora lo quito para no inducir a error.
Bueno, animado por la respuesta de Aiken, por fin me he decidido a probar el C++ con el GCC.
No sé como lo hice hace 2 años, pero hoy no estoy teniendo problemas, salvo el de preparar correctamente las cabeceras de las librerías gpfont16.h y gpgraphic16.h
Aparte de esto ningún problema por el momento.
Aquí os pongo el código con ejemplos sacados de http://www.cplusplus.com/doc/tutorial/:
#include <gpdef.h>
#include <gpstdlib.h>
#include <gpfont16.h>
#include "gpmain.h"
GPDRAWSURFACE gtSurface[2];
int giSurface;
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area (void) {return (x*y);}
};
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
class CRectangle2 {
int width, height;
public:
CRectangle2 (int,int);
int area (void) {return (width*height);}
};
CRectangle2::CRectangle2 (int a, int b) {
width = a;
height = b;
}
// Initialize graphics mode
void InitGraphics(int depth)
{
// Initialize graphic mode
GpGraphicModeSet(depth, NULL);
// Crea les superficies
GpLcdSurfaceGet(>Surface[0], 0);
GpLcdSurfaceGet(>Surface[1], 1);
// Register surfaces
giSurface = 0;
GpSurfaceSet(>Surface[giSurface]);
// Activates LCD if needed
if (!(GpLcdStatusGet() & GPC_LCD_ON_BIT))
GpLcdEnable();
giSurface = 1;
}
int divide (int a, int b=2)
{
int r;
r=a/b;
return (r);
}
void prevnext (int x, int& prev, int& next)
{
prev = x-1;
next = x+1;
}
void GpMain (void * arg)
{
int i, j;
char str[30];
CRectangle rect;
CRectangle2 rect2 (4,6);
InitGraphics(16);
GpTextOut16(NULL, >Surface[giSurface], 0, 0, "Ejemplo C++ en 16 bits", 0);
prevnext(1, i, j);
gm_sprintf(str, "i=%ld, j=%ld", i, j);
GpTextOut16(NULL, >Surface[giSurface], 0, 20, str, 0);
i = divide(12);
j = divide(12, 4);
gm_sprintf(str, "i=%ld, j=%ld", i, j);
GpTextOut16(NULL, >Surface[giSurface], 0, 40, str, 0);
rect.set_values (3,4);
gm_sprintf(str, "area=%ld, area2=%ld", rect.area(), rect2.area());
GpTextOut16(NULL, >Surface[giSurface], 0, 60, str, 0);
gm_sprintf(str, "memoria=%ld", gm_availablesize());
GpTextOut16(NULL, >Surface[giSurface], 0, 220, str, 0);
GpSurfaceFlip(>Surface[giSurface++]);
giSurface &= 0x01;
while (TRUE);
}
Ahora voy a ver que tal los problemas de memoria con los constructores y desctructores.
Os mantendré informados.
Pues hasta aquí hemos llegado, a la que utilizo los operadores new/delete ya no funciona.
He descargado el parche de Mr.Spiv gracias a un post incontestado de Aiken de hace la tira de tiempo, pero, como él, no hay manera de hacerlo funcionar.
Aunque me parece que estoy cerquita.
Me he puesto en contacto con Mr.Spiv. A ver si me contesta.
Oankali.
anibarro
13/07/2005, 16:39
Nos mantenemos a la escucha :brindis:
D_Skywalk
13/07/2005, 20:08
Pues hasta aquí hemos llegado, a la que utilizo los operadores new/delete ya no funciona.
He descargado el parche de Mr.Spiv gracias a un post incontestado de Aiken de hace la tira de tiempo, pero, como él, no hay manera de hacerlo funcionar.
Aunque me parece que estoy cerquita.
Me he puesto en contacto con Mr.Spiv. A ver si me contesta.
Oankali.
Oankali, has mirado en el mirkoSDK? hay un par de ejemplos de C++ donde puedes ver como crea y destruye objetos sin problema :?
Es mas la libreria de una-i es C++ puro y duro xD
Un Saludo :)
Pues hasta aquí hemos llegado, a la que utilizo los operadores new/delete ya no funciona.
He descargado el parche de Mr.Spiv gracias a un post incontestado de Aiken de hace la tira de tiempo, pero, como él, no hay manera de hacerlo funcionar.
Aunque me parece que estoy cerquita.
Me he puesto en contacto con Mr.Spiv. A ver si me contesta.
Oankali.
Yo uso algo tal que asi y no hay ningun problema, lo del appmain te lo puedes saltar, solo es importante la redefinicion del operador new y delete.
Esto es con el sdk de mirko, no se si en las veriones modernas lo habran arreglado, en el sdk oficila supongo que tendras que llamar a gp_malloc o como se llame y listo.
///////////////////////////////////////////////////////////////////////////
// Description
//
///////////////////////////////////////////////////////////////////////////
int main()
{
AppMain();
gp_Reset();
return 0;
}
///////////////////////////////////////////////////////////////////////////
void* operator new(long unsigned int size)
{
return malloc(size);
}
///////////////////////////////////////////////////////////////////////////
void* operator new[](long unsigned int size)
{
return malloc(size);
}
///////////////////////////////////////////////////////////////////////////
void operator delete(void* p)
{
free(p);
}
///////////////////////////////////////////////////////////////////////////
void operator delete[](void* p)
{
free(p);
}
Mr.Spiv me ha contestado que con el devkitARM en principio tendría que funcionar sin parche, pero no lo he conseguido.
Eso sí, si añado estas líneas (gracias Una-i):
void* operator new(long unsigned int size)
{
return gm_malloc(size);
}
void* operator new[](long unsigned int size)
{
return gm_malloc(size);
}
void operator delete(void* p)
{
gm_free(p);
}
void operator delete[](void* p)
{
gm_free(p);
}
ya solo me queda un error:
gpmain.o: In function `Example5()':
gpmain.cpp:(.text+0x478): undefined reference to `__gxx_personality_sj0'
collect2: ld returned 1 exit status
make: *** [testCPP.elf] Error 1
¿Será mi makefile?
Aquí os cuelgo todo el proyecto.
Oankali.
Trasteando un poco más, me he cargado los operadores new y delete del código cambiándolos directamente por las funciones gm_free() y gm_malloc().
Me sigue dando el mismo error que antes, o sea que ese error no tiene nada que ver con estos dos operadores.
El error: gpmain.cpp.text: undefined reference to `__gxx_personality_sj0'
lo provoca el destructor de la clase.
A la que elimino el destructor, ya funciona.
Esto no es una solución, pero era para ayudaros a ayudarme :)
Oankali.
Salustian
14/07/2005, 09:04
Bucenado por google he encontrado esto:
Exceptions are not supported. Since exceptions are enabled by default in the C++ frontend, they explicitly need to be turned off using -fno-exceptions in the compiler options. Failing this, the linker will complain about an undefined external reference to __gxx_personality_sj0.
La fuente es:
http://www.sigterm.de/projects/sens-o-nuts/Dokumentation/atmel/libc/FAQ.html
Pruébalo y ya nos dirás.
Un saludo.
Salustian
14/07/2005, 09:18
He compilado tu ejemplo añadiendo
CPPFLAGS = $(CFLAGS) -fno-exceptions
en el makefile y tu error desaparece.
sin embargo yo obtengo el siguiente:
gpmain.o: In function `MainScreen()':
gpmain.cpp:(.text+0x1a0): undefined reference to `GpTextOut16(tagGPDRAWTAG*, tag
GPDRAWSURFACE*, int, int, char*, int)'
si cambio GpTextOut16 por GpTextOut compila a la perfección.
¿A ti no te pasa lo mismo?
Un saludo.
Ya me funciona inhabilitando las excepciones.
Lo que va aprendiendo uno. Es que nunca he programado en C++ y por lo visto es algo más chungo que el C.
Lo del error que te sale a mí no me sale porqué he corregido el archivo de cabecera gpfont16.h.
Le falta los típicos:
#ifdef __cplusplus
extern "C" {
#endif
.
.
.
#ifdef __cplusplus
}
#endif
También hay que corregir gpgraphic16.h.
Cuando tenga un momento actualizaré los archivos que tengo en mi web con el SDK de 16 bits y también el Makefile.
Bueno, al final va a resultar que sí se puede programar en C++ con el SDK oficial aunque con algunas restricciones: no utilizar excepciones. O puede que sí se puede y no sabemos como se hace. Aunque por lo que he leído, las excepciones aumentan bastante el código de la aplicación y para programas pequeños no sale a cuenta.
Solo me falta probar a ver si también funciona con el SDK para Windows.
anibarro
14/07/2005, 11:04
Tantas veces que se había preguntado esto y por fin resuelto :D :D :D muchas gracias, ya mismo me pongo a re-reconvertir lo que había pasado de c++ a c xD
Bueno, pues parecer ser que con el SDK para Windows funciona y no funciona.
Resulta que funciona sin declarar los operadores new/delete de Una-i porque no hace falta.
Pero eso significa que el VC++ llama a los operadores new/delete estándar. Con lo cual, no se hace uso de gm_malloc() i gm_free(). Resultado: no se puede controlar la memoria con gm_availablesize().
Tampoco es tan importante ya que al fin y al cabo, si se puede controlar en el código ARM para la GP32, ya es suficiente, pero ya me gustaba a mí saber desde Windows cuanta memoria utilizaban mis rutinas.
Tendré que buscar una forma de integrar todo esto correctamente en el SDK oficial que tengo en mi web para que sea lo más transparente posible para el programador. Y así olvidarnos de una vez por todas de la típica pregunta "¿Se puede C++, o no se puede?" :musico:
Oankali.
the_goulin
14/07/2005, 14:57
Bueno, pues parecer ser que con el SDK para Windows funciona y no funciona.
Resulta que funciona sin declarar los operadores new/delete de Una-i porque no hace falta.
Pero eso significa que el VC++ llama a los operadores new/delete estándar. Con lo cual, no se hace uso de gm_malloc() i gm_free(). Resultado: no se puede controlar la memoria con gm_availablesize().
Tampoco es tan importante ya que al fin y al cabo, si se puede controlar en el código ARM para la GP32, ya es suficiente, pero ya me gustaba a mí saber desde Windows cuanta memoria utilizaban mis rutinas.
Tendré que buscar una forma de integrar todo esto correctamente en el SDK oficial que tengo en mi web para que sea lo más transparente posible para el programador. Y así olvidarnos de una vez por todas de la típica pregunta "¿Se puede C++, o no se puede?" :musico:
Oankali.
:D uauu, siento no haber podido participar más en la investigacion ya que en estos momentos no tengo internet en casa.
Muchas gracias a todos los que investigais tanto para dar por fin con la solución, Oankali espero ansioso la actualizacion de tu web :)
Saludillos,
The_Goulin
Bueno, pues parecer ser que con el SDK para Windows funciona y no funciona.
Resulta que funciona sin declarar los operadores new/delete de Una-i porque no hace falta.
Pero eso significa que el VC++ llama a los operadores new/delete estándar. Con lo cual, no se hace uso de gm_malloc() i gm_free(). Resultado: no se puede controlar la memoria con gm_availablesize().
Tampoco es tan importante ya que al fin y al cabo, si se puede controlar en el código ARM para la GP32, ya es suficiente, pero ya me gustaba a mí saber desde Windows cuanta memoria utilizaban mis rutinas.
Tendré que buscar una forma de integrar todo esto correctamente en el SDK oficial que tengo en mi web para que sea lo más transparente posible para el programador. Y así olvidarnos de una vez por todas de la típica pregunta "¿Se puede C++, o no se puede?" :musico:
Oankali.
Tienes razón si, yo tambien he conseguido compilar tu ejemplo con el sdk para windows, con gcc para gp no he probado. Al principio daba error en el new y delete pero quitandolos ha ido sin problemas.
Es bueno saber que se puede usar c++ porque con c puro y duro me estoy volviendo un poco loco a veces :D
anibarro
15/07/2005, 01:38
Oankali, en el programita que has puesto de ejemplo usas el arm-elf-gcc y no da errores, pero al compilar un programa que tenía, he tenido que usar el arm-elf-g++ para que no diese errores...y creo que por eso ahora tengo problemas a reservar memoria.
En la versión convertida de c++ a c de la GP, cambie los realloc por gm_free y gm_malloc, funcionando sin problemas. Ahora copiando y pegando todo igual, pero usando las clase original de c++, me devuelve NULL al reservar con gm_malloc (memoria hay de sobra pq es la primera reserva) y supongo que tiene que ser culpa de usar g++ porque las librerías y el código es todo igual, y solo falla con las funciones de reservar memoria, aunque compila sin errores.
He probado tb a usar new y delete si redefinirlas y redefiniendolas y tampoco funciona :llorosr:
Oankali, en el programita que has puesto de ejemplo usas el arm-elf-gcc y no da errores, pero al compilar un programa que tenía, he tenido que usar el arm-elf-g++ para que no diese errores...y creo que por eso ahora tengo problemas a reservar memoria.
En la versión convertida de c++ a c de la GP, cambie los realloc por gm_free y gm_malloc, funcionando sin problemas. Ahora copiando y pegando todo igual, pero usando las clase original de c++, me devuelve NULL al reservar con gm_malloc (memoria hay de sobra pq es la primera reserva) y supongo que tiene que ser culpa de usar g++ porque las librerías y el código es todo igual, y solo falla con las funciones de reservar memoria, aunque compila sin errores.
He probado tb a usar new y delete si redefinirlas y redefiniendolas y tampoco funciona :llorosr:
Pues a mi me compila con g++, aquí tienes la prueba:
>make
arm-elf-g++ -marm -march=armv4t -mapcs -O2 -fomit-frame-pointer -finline-functions -fshort-enums -ffast-math -fshort-double -mstructure-size-boundary=8 -mno-thumb-interwork -Wno-multichar -IC:/devkitARM/gamepark_sdk/include -I. -fno-exceptions -c -o gpmain.o gpmain.cpp
arm-elf-gcc -o testCPP.elf C:/devkitARM/gamepark_sdk/gpstart.o gpmain.o -specs=gp32_gpsdk.specs -Wl,-Map,testCPP.map -LC:/devkitARM/gamepark_sdk/lib -lgpgraphic -lgpgraphic16 -lgpmem -lgpos -lgpstdlib -lgpstdio -lgpsound -lgpg_ex01 -lgpfont -lgpfont16 -lm -lc
arm-elf-objcopy -O binary testCPP.elf testCPP.gxb
>Exit code: 0
Y aquí tienes el ejemplo completo, con makefile y .gxb y verás que la alocación de memoria funciona correctamente.
anibarro
15/07/2005, 11:03
pues sí funcionan bien... :rolleyes: no reservaba la memoria pq las variables que se usan para decir la cantidad de memoria, aunque están definidas e inicializadas en el constructor, no se inicializan no se por que y se quedan a 0 :S Al final parace que se puede programar sin problemas en C++ ^^ :brindis:
pues sí funcionan bien... :rolleyes: no reservaba la memoria pq las variables que se usan para decir la cantidad de memoria, aunque están definidas e inicializadas en el constructor, no se inicializan no se por que y se quedan a 0 :S Al final parace que se puede programar sin problemas en C++ ^^ :brindis:
eso lo podriais solucionar a la "vieja usanza" en los operadores new y delete reimplementados modificar las variables de memoria del sdk tanto en la "version windows" como en la normal.
Eso es facil a allocar porque sabes cuanto bytes llebas pero dificil al liberar porque no sabes de cuantos bytes fue la reserba.
Paa solucionar ese problemilla podeis hacer 2 cosas una hacer un poco de ingenieria inversa y mirar digamos... los 16 bytes anteriores al puntero que devuelve gp_malloc que me apostatia el cuello a que esta ahi almacenado el tamño del bloque y lo mismo con el puntero que devuleva malloc en windows.
Yo en mis historias tengo las coas compilando para win o gp y en ambos casos redefino los operadore new/delete a mallos/free, que con el sdk no oficial funciona en las dos circunstancias, vosotros lo que tendriais que hacer es tenr dos .cpp memoria_gp32.cpp y memopria_win.cpp y selecionar un u otro en el makefile, metiene la implementacion del new/te que agatodos los apanos anteriores...
En fins suerte...
anibarro
17/07/2005, 02:01
una-i, si al final new y delete funcionan muy bien, al menos hasta donde los he probado yo. El problema era que tengo definida una clase, en la que el constructor se limita a inicializar unas variables de la clase, pero despues de crear un objeto de esa clase, resulta que es como si no se hubiese llamado al constructor, porque no inicializa las variables. Por ejemplo, en el constructor de la clase LANDSCAPE hay una linea:
Speed=10;
Y defino en el programa un objeto de esa clase:
LANDSCAPE Land;
si justo después miro el valor de Land.Speed, es 0, en lugar de 10 como se supone q debería ser...y como variables que se inicializaban en el constructor, las usaba para saber el tamaño de memoria a reservar, gm_malloc y new me devolvían NULL pq esas variables valían 0, pero funcionan bien si defino a mano las variables :/
[...]
Yo en mis historias tengo las coas compilando para win o gp y en ambos casos redefino los operadore new/delete a mallos/free, que con el sdk no oficial funciona en las dos circunstancias, vosotros lo que tendriais que hacer es tenr dos .cpp memoria_gp32.cpp y memopria_win.cpp y selecionar un u otro en el makefile, metiene la implementacion del new/te que agatodos los apanos anteriores...
En fins suerte...
Esto es lo que pensaba hacer pero no sé como redefinir los operadores new/delete en VC++.
Si los defino simplemente que el código que pusiste más arriba, el programa compila correctamente pero no se ejecutan esas líneas.
¿Cómo se hace?
Como puedes ver, yo de C++ ni idea.
Oankali.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.