forumti.gif
@_ö
(01:04)  Bienvenue ! - Inscrivez vous pour poster ! -
@Boo, Nhut, Fei, pal0uf, 37 inconnu(s), 18 bot(s)

Login :  Mot de passe :      Se souvenir de moi.  Mot de passe perdu ?
/!\:: Cliquez ici pour vous inscrire et poster, créer des sujets ou des forums ! ::/!\
 « - 1/14 - Suivant » :: Pages
 Index » Forum Ti 89, Titanium / 92+ / Voyage 200 et TI-Nspire » Prog C TI (398r) » Librairie dynamique
./Post de départ - Librairie dynamique
18.06.2001 - 27049
14:04  Folco - Posté : 12-11-2009  M
yop,

J'aimerais savoir comment faire une lib dynamique en C. Dans la doc, il ya ça :
You can produce an external library file by defining the global symbol _library, i.e. by putting int _library in your program.

Ca veut dire que je mets "int _library;" quelque part et c'est bon ? C'est tout ?!?
./Publicité AdSense
./1
10.06.2001 - 33210
14:07  Kevin Kofler - Posté : 12-11-2009  M
Oui. (Enfin, il faut aussi définir USE_KERNEL évidemment, cf. options du projet si tu utilises l'EDI.)
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./2
18.06.2001 - 27049
14:42  Folco - Posté : 12-11-2009  M
Ok, merci. happy
./3
28.08.2003 - 8284
14:59  Sasume - Posté : 12-11-2009  M
Genre tu fais du C.
avatar« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
./4
18.06.2001 - 27049
14:59  Folco - Posté : 12-11-2009  M
Ouais grin
./5
18.06.2001 - 27049
15:00  Folco - Posté : 12-11-2009  M
On s'endort presque à utiliser genlib en C, tout est déjà fait. grin

truc

void gl_main()
{
while( 1 )
{
// Manage non-graphical part
switch( Task )
{
}

// Wait for real screen swapping
glaux_ready();

// Manage graphical part
switch( Task )
{
}

// Wait for synchro
glaux_synchro( 1 );
glaux_swap();
}

}
./6
18.06.2001 - 27049
15:05  Folco - Posté : 12-11-2009  M
Tiens ben pendant que j'y suis, une question.

Si j'ai deux fonctions, A et B, sans "return", mais dans lesquelles elles s'appellent mutuellement, est-ce que le programme va empiler des adresses de retour sur la pile ?
ie en assembleur, j'aurais fait des bra entre les fonctions, pas des bsr.
Ca se gère comment en C ? tout seul j'espère ?
./7
10.06.2001 - 33210
15:09  Kevin Kofler - Posté : 12-11-2009  M
Ça va générer le bordel sur la pile effectivement, sauf dans les cas où une optimisation tailcall est possible.

Il vaut mieux travailler avec des boucles ou des goto dans ce cas.
Edité par Kevin Kofler le 12-11-2009 à 15:10:37.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./8
28.10.2001 - 7499
15:10  Lionel Debroux - Posté : 12-11-2009  M
Si l'optimiseur de flot de contrôle de GCC 1) sait faire cette optimisation sur les fonctions qui s'appellement mutuellement (attention à la terminaison de la récursivité grin) et 2) arrive dans ton cas à déterminer qu'il peut faire cette optimisation, alors il la fera.
avatarMembre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
./9
16.06.2001 - 61202
15:13  squalyl - Posté : 12-11-2009  M
(cross, réponse à martial)

non. ça va s'appeler récursivement et remplir la pile.

ce que tu veux faire ça s'appelle des threads/couroutines/tâches, faut deux piles différentes et utiliser un truc de taskswitch préemptif style je-sais-plus-le-nm-du-truc-de-ximoon

alternativement ça peut se faire assez simplement (sisi #trioui#) avec setjmp

https://www.unsads.com/scm/svn/squalyl/asi/systeme/P3S/test/switcher-ti68k/
user guest
pass guest

(je sais plus si c'est complet, je sais plus si ça marche, mais le principe y est. Dommage j'avais un truc encore plus simple que ça, je le retrouve plus sad )

edit: ah le voila

#include <stdio.h>
#include <setjmp.h>

/*
| context switch presque portable avec setjmp, longjmp
| pour comprendre setjmp et longjmp voir la doc :
| http://www-ensimag.imag.fr/cours/Systeme/setjmp.longjmp
|
*/

#define K 1024
#define TAILLE_PILE 4*K

int mem [TAILLE_PILE]; /* memoire pour la pile du processus 1 */
int * deb_mem;
int proc_actif = 0;
jmp_buf buf_processus[2];

/*----------------------------------------------------------------------------*/
void ctxsw(actif, elu) {
if (setjmp(buf_processus[actif]) == 0) {
proc_actif = elu;
longjmp(buf_processus[elu], 1);
}
}
/*----------------------------------------------------------------------------*/
int choix_elu() {
if (proc_actif == 0) return 1; else return 0;
}
/*----------------------------------------------------------------------------*/
void resched() {
int proc_elu;
proc_elu = choix_elu();
ctxsw(proc_actif, proc_elu);
}
/*----------------------------------------------------------------------------*/
/*
| code execute par les 2 processus
|
*/
void code_processus(char * mess) {
int i;
while(1) {
printf ("%s", mess);
resched(); /* changement de processus */
}
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int main() {
deb_mem = mem; /* on pourrait faire un malloc a la place */
/*
| ici c'est le processus 0 qui s'exécute avec la pile allouée au lancement du programme C
*/
if (setjmp(buf_processus[1]) == 0) {
#ifdef LINUX
/*
| Initialisation de la pile pour le processus 1 (petit bricolage specifique pour linux/i386)
*/
buf_processus[1][0].__jmpbuf[JB_SP] = deb_mem + TAILLE_PILE;
#else
#ifdef SOLARIS
/*
| Initialisation de la pile pour le processus 1
| (petit bricolage specifique pour Solaris/Sparc)
*/
buf_processus[1][1] = (int) deb_mem + TAILLE_PILE - 16;
#else
#error "use -DLINUX or -DSOLARIS"
#endif
#endif
printf ("Je suis le processus 0 et je pars dans la boucle\n");
code_processus("je pense\n");
} else {
printf ("Je suis le processus 1 et je pars dans la boucle\n");
code_processus(" donc tu es\n");
}
}
Edité par squalyl le 12-11-2009 à 15:25:36.
./10
10.06.2001 - 33210
15:21  Kevin Kofler - Posté : 12-11-2009  M
Pour la TI, le code spécifique à la plateforme, c'est:
buf_processus[1]->A7 = (unsigned long) deb_mem + TAILLE_PILE;

Mais ce hack est vraiment #sick#! (Enfin, mon Task Switcher contient pire que ça, hein.)
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./11
16.06.2001 - 61202
15:23  squalyl - Posté : 12-11-2009  M
oui ce hack est mégamoche mais franchement tu connais d'autres moyens? c'est toujours la même histoire non? allocation de l'espace mémoire du nouveau processus, et changement de SP/PC plus autres registres (bien entendu sur pc c'est carrément plus compliqué avec les mmu et etc). SetJmp n'est qu'un outil userspace pratique pour les besoins de la démo.

d'ailleurs pour avoir testé ça marche très bien sur 68k.
./12
18.06.2001 - 27049
15:28  Folco - Posté : 12-11-2009  M
Kevin Kofler (./7) :
Ça va générer le bordel sur la pile effectivement, sauf dans les cas où une optimisation tailcall est possible.

Il vaut mieux travailler avec des boucles ou des goto dans ce cas.

Ok, je vais m'organiser autrement.
squalyl (./9) :
ce que tu veux faire ça s'appelle des threads/couroutines/tâches, faut deux piles différentes et utiliser un truc de taskswitch préemptif style je-sais-plus-le-nm-du-truc-de-ximoon

alternativement ça peut se faire assez simplement (sisi /v31/gfx/s3/trioui.gif ) avec setjmp

Hmm t'as vraiment pas plus simple #trilove#

Regarde à quel point j'en suis techniquement :
	char * Buffer[10] ;

sprintf( Buffer , "unmap%u" , Level );

J'aurais voulu savoir si c'est valide. Il va bien y avoir un 0 à la fin de "unmap%u" ? cheeky Ou dois-je écrire "unamp%u\0" ?

PS -> Ca fait bien deux octets un int sur TI ?

edit :
	sprintf( Buffer , "unmap%hu" , Level );
MapDesc = LibsBegin( Buffer , 0 );

Faut inclure quoi pour avoir les ramcalls ? J'ai inclus tigcclib.h, j'ai fait un #define USE_KERNEL, mais il veut pas de mon LibsBegin #ouin#
Edité par Folco le 12-11-2009 à 15:30:59.
./13
10.06.2001 - 33210
15:29  Kevin Kofler - Posté : 12-11-2009  M
squalyl (./11) :
oui ce hack est mégamoche mais franchement tu connais d'autres moyens?

L'autre moyen, c'est de faire une seule fonction avec des goto, voire une simple boucle si le fonctionnement est suffisamment régulier.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./14
10.06.2001 - 33210
15:32  Kevin Kofler - Posté : 12-11-2009  M
Folco (./12) :
Regarde à quel point j'en suis techniquement :
	char * Buffer[10] ;

sprintf( Buffer , "unmap%u" , Level );

J'aurais voulu savoir si c'est valide.

Non. Un %u peut faire jusqu'à 5 caractères ("65535"), plus les 5 du "unmap" plus le \0, ça fait 11, donc ton buffer est trop petit.

Il va bien y avoir un 0 à la fin de "unmap%u" ? cheeky

Oui. Mais il faut le compter dans ta taille du buffer aussi!

Ou dois-je écrire "unamp%u\0" ?

Non.

PS -> Ca fait bien deux octets un int sur TI ?

Oui.
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./15
18.06.2001 - 27049
15:42  Folco - Posté : 12-11-2009  M
Merci pour tout. smile
En fait, mon argument "Level" ne peut dépasser 3 caractères, donc ça ira. C'est pour construire un nom de fichier.


Par contre, j'ai un problème qui me gave bien, ça fait patrie des trucs du C qui ressemblent pour moi à une machinerie assez obscure :
J'inclus "genlib.h". Dans la doc de genlib, c'est écrit ça :
And you don’t need to include tigcclib since genlib.h do it for you.

Et apparemment, tigcclib ne connait pas LibsBegin.

Je vais donc pour inclure kernel.h de PreOS, header kernel pour le C. Mais dans le header, je trouve ça :
#if defined(NOSTUB) || defined(KERNEL) || defined(DOORS)
# error "kernel.h" must not be included with tigcclib.h
#endif

Et c'est con, parce que dedans, il y a les définitions des romcalls. sad

Comment faire alors ? PpHd, c'est quoi les règles de l'art en la matière ?
./16
28.08.2003 - 8284
15:47  Sasume - Posté : 12-11-2009  M
./6 Euh je ne comprends pas pourquoi squalyl te parle de tout ça… #trifus#
Si effectivement tes fonctions s’appellent de façon croisée et non conditionnelle (à l’extérieur d’un if) ton programme ne terminera pas (enfin au moment du stack overflow seulement grin ).
Pour résoudre ça le mieux est de faire des boucles, et le moins mieux est d’utiliser goto.

[edit] : un dernier truc : teste ton code toutes les 10 lignes. Évite d’écrire des pages et des pages sans même voir si ça compile ou sans même tester si la fonctionnalité ajoutée fonctionne comme prévu.
avatar« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
./17
18.06.2001 - 27049
15:50  Folco - Posté : 12-11-2009  M
Merci pour les tips. Pour ce qui est de la compilation, t'inquiète pas, je suis tellement skillé que je suis obligé de tester à chaque ligne. #trioui#
C'est vrai qu'en assembleur, je peux écrire beaucoup sans relire ou tester, mais là c'est pas la peine. grin
./18
28.10.2001 - 7499
15:52  Lionel Debroux - Posté : 12-11-2009  M
Un "int" fait 2 octets sur TI-68k (sauf si tu actives une option à la con du compilo, auquel cas les fonctions de la famille *printf ne vont plus fonctionner correctement, parce qu'elles supposent qu'un int fait 2 octets grin), mais 4 sur la plupart des plate-formes actuelles. Utiliser "int" n'a pas que des avantages.
Tu peux utiliser "short", "unsigned short", "int16_t" ou "uint16_t" (les deux derniers sont dans le header <stdint.h>, qui est inclus par <inttypes.h>) si tu veux une variable 16 bits (.w), et "long", "unsigned long", "int32_t" ou "uint32_t" si tu veux une variable 32 bits.
avatarMembre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
./19
18.06.2001 - 27049
16:21  Folco - Posté : 12-11-2009  M
Bon, j'ai résoudru le problème de la pile : main est un scheduler qui appelle la fonction qui va bien :

schedule

void gl_main()
{
while(1)
{
// Schedule tasks
switch( NextTask )
{
case TASK_EXIT:
return;
case TASK_INTRO:
LoadIntro();
break;
case TASK_GAME:
LoadGame();
break;
}
CurTask = NextTask ;
InfiniteLoop();
}
}

Et dans InfiniteLoop(), on fait un return si CurTask a été mis à 0 par la tâche en cours.

C'est bien. smile
Enfin presque, faut que je trouve un moyen de faire passer une valeur d'une fonction à une autre maintenant...
./20
18.06.2001 - 27049
17:09  Folco - Posté : 12-11-2009  M
Tiens, j'avais pas vu ce warning, j'en reste #confus#, bien que je fasse sûrement une erreur :
Le proto de sprintf :
short sprintf (char *buffer, const char *format, ...);

Mon code :
	char * Buffer[ 10 ] ;
const char * Filename = "unmap%u" ;

sprintf( Buffer , Filename , Level );

Level est un int. J'ai ce ouarningue :
game.c:17: warning: passing argument 1 of '(<U9e70> = &_ROM_CALL_53)' from incompatible pointer type

Pourquoi ?
./21
13.06.2002 - 38250
17:17  @Zeph - Posté : 12-11-2009  M
Parceque ton buffer, tel que déclaré, est un tableau de pointeurs vers des "char". Ce que sprintf attend c'est juste un tableau de char (donc au choix "char Buffer[10]" ou "char* Buffer" selon que tu veux du statique ou du dynamique).
avatarHello and, again, welcome to the Aperture Science computer-aided Enrichment Center.
------------------------------------------
:: It offers what you want, not what you need
3l33t :: Relax, we understand j00 ^^
./22
18.06.2001 - 27049
17:22  Folco - Posté : 12-11-2009  M
Ah, parce que un tableau est un pointeur, donc "char Buffer[10 ] est un pointeur. Merci ! smile
./23
28.08.2003 - 8284
17:26  Sasume - Posté : 12-11-2009  M
Disons plutôt que, après la déclaration :
char buffer[10];

On a :
« buffer » est un « char * »
« buffer[n] » est un « char »
avatar« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
./24
18.06.2001 - 27049
17:34  Folco - Posté : 12-11-2009  M
Ok, merci pour ça. happy
./25
11.06.2001 - 19135
19:03  PpHd - Posté : 12-11-2009  M
Folco (./15) :
Merci pour tout. smile
En fait, mon argument "Level" ne peut dépasser 3 caractères, donc ça ira. C'est pour construire un nom de fichier.


Par contre, j'ai un problème qui me gave bien, ça fait patrie des trucs du C qui ressemblent pour moi à une machinerie assez obscure :
J'inclus "genlib.h". Dans la doc de genlib, c'est écrit ça :
And you don’t need to include tigcclib since genlib.h do it for you.

Et apparemment, tigcclib ne connait pas LibsBegin.

Je vais donc pour inclure kernel.h de PreOS, header kernel pour le C. Mais dans le header, je trouve ça :
#if defined(NOSTUB) || defined(KERNEL) || defined(DOORS)
# error "kernel.h" must not be included with tigcclib.h
#endif

Et c'est con, parce que dedans, il y a les définitions des romcalls. sad

Comment faire alors ? PpHd, c'est quoi les règles de l'art en la matière ?


#include "kernel.h"
#include "genlib.h"

doit marcher.
./26
11.06.2001 - 19135
19:03  PpHd - Posté : 12-11-2009  M
Folco (./5) :
On s'endort presque à utiliser genlib en C, tout est déjà fait. grin

truc

void gl_main()
{
while( 1 )
{
// Manage non-graphical part
switch( Task )
{
}

// Wait for real screen swapping
glaux_ready();

// Manage graphical part
switch( Task )
{
}

// Wait for synchro
glaux_synchro( 1 );
glaux_swap();
}

}


C'est fait pour!
./27
18.06.2001 - 27049
19:37  Folco - Posté : 12-11-2009  M
Merci ! Mais j'ai fait un testcase minimal qui ressemble à ./26, et j'obtiens ça :
/opt/gcc4ti/lib/tigcc.a: Error: Unresolved reference to `__main'.

C'est vrai que les headers C, c'est compliqué avec cette manière de pouvoir dé-définir des symboles...

En plus, quand je compile avec "-Wa,-l", il me dit
1. Que j'ai encore de l'espace à gagner avec le switch -l de GAS !!
2. Que les ramcalls peuvent pas être relatifs (sans blague) et qu'il les passe en absolu.
Edité par Folco le 12-11-2009 à 20:23:47.
./28
11.06.2001 - 19135
20:15  PpHd - Posté : 12-11-2009  M
Ajoute #define _main __main tout en haut avant le premier include.
./29
18.06.2001 - 27049
20:20  Folco - Posté : 12-11-2009  M
Miracle, ça marche, bien joué. smile

Pour faire propre, ce #define doit aller où ?

edit -> je veux dire, dans quel header grin
./Publicité AdSense
 « - 1/14 - Suivant » :: Pages
 Index » Forum Ti 89, Titanium / 92+ / Voyage 200 et TI-Nspire » Prog C TI (398r) » Librairie dynamique

./Poster un nouveau message. - Ouvrir dans une nouvelle fenêtre
Login : Mot de passe :

url - image - media  
spoiler - pre - fixed
quote - box - hr
poll - code





Smileys
Smileys perso
Pièce jointe
     Flood control (?) :    
Les messages postés sont la propriété de leurs auteurs. Nous ne sommes pas responsables de leurs contenus.

» yN ©1624 - Aide / Charte / Crédits
36ms | Statistiques