210

Nooun, je suis désolé, j'ai toujours ton bouquin de C, et je pesne qu'il serait sans doute plus utile chez toi que chez moi.
...

211

Kevin: ne mélange pas jni et JIT

extrait de jni.h trouvé sur google codesearch

void (JNICALL *CallVoidMethod)(JNIEnv *env, jobject obj, jmethodID methodID, ...);
void (JNICALL *CallVoidMethodV)(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
void (JNICALL *CallVoidMethodA)(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);

on obtient un identifiant de méthode grâce à son nom et à une signature de type avec l'api:

jmethodID (JNICALL *GetMethodID)(JNIEnv *env, jclass clazz, const char *name, const char *sig);

On connait donc le type des args à pousser et on peut faire comme on veut pour s'en servir (pile controlée ou libffi)
mais c'est un autre problème, et l'api JNI utilise bien stdarg.

212

Zephyr (./209) :
./205 : bah ça m'a pas l'air insurmontable tout ça ? la responsabilité du nettoyage de la pile peut changer, on peut avoir à aligner les données sur une taille dépendant de l'archi, etc... mais ça reste des variations assez triviales d'un même modèle ; d'ailleurs libffi a l'air de faire exactement ce que j'attendais, comme quoi c'est pas si impossible que ça ^^ (merci Kevin pour le lien)
Oui mais c'est implémenté de manière non portable, comme j'ai expliqué ^^
En gros ce qui est portable, c'est l'interface (libffi), pas le code derrière.
Et sinon, non y'a rien d'insurmontable, faut juste que tu portes le code pour chaque architecture+plateforme que tu veux supporter smile
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

213

GoldenCrystal (./212) :
En gros ce qui est portable, c'est l'interface (libffi), pas le code derrière.


C'est le but de ce genre de lib non? triso

214

oui, si ce que tu voulais dire était simplement "c'est techniquement possible mais c'est pas portable puisque ça dépend de l'archi", c'était pas la peine de faire des posts aussi longs happy
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

215

./213 > Ouais tout à fait ^^
Mais c'est pas un truc standard, juste un truc qui a fait le boulot chiant à ta place smile
(Et accessoirement, non je connaissais pas libffi tongue)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

216

RiRi (./210) :
Nooun, je suis désolé, j'ai toujours ton bouquin de C, et je pesne qu'il serait sans doute plus utile chez toi que chez moi.

Parfait \o/ mais ya pas de mal smile

J'y pensais justment en me connectant vois-tu, c'est vrai que j'arrive à faire ce que je veux, mais sans maitriser des mécanismes qui sont malgré tout indispensables pour avancer fort et proprement.

On verra ça à la prochaine occaz. wink

217

« Nooun » hehe
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

218

Ils ont leurs petits noms on dirait cheeky

219

Pen^2 (./218) :
Ils ont leurs petits noms on dirait cheeky

Oui, mais il était raccourci et en plus avec une faute de frappe^^
...

220

Folco (./191) :
De quelle manière un programme kernel compilé avec --remove-unused peut-il faire que 89 octets, alors qu'il devrait en faire dans les 300 ? main() appelle a() qui appelle b() qui dessine à l'écran. Quand j'enlève --remove-unused, tout rentre dans l'ordre (enfin, presque).
main.c
#include  "unedit.h"
#include  "kernel.h"
#include  "genlib.h"
#include  "funcs.h"
#include  "vars.h"

unsigned short MapWidth = 0;
unsigned short MapHeight = 0;
const SCR_RECT Clip = {{0,0,239,127}};

void main(void)
{
  NewMap();
}

et le fichier qui contient newmap :
menu.c
#include  "unedit.h"
#include  "kernel.h"
#include  "genlib.h"
#include  "funcs.h"
#include  "vars.h"

void DrawBox(char* title)
{
  ScrRectFill (&Clip, &Clip, A_REVERSE);
  ScrRectFill (&(SCR_RECT){{0,0,239,15}}, &(SCR_RECT)Clip, A_NORMAL);
  DrawStr (3, 3, title, A_REVERSE);
  DrawClipRect (&(WIN_RECT){0,0,159,99}, &(SCR_RECT)Clip, B_DOUBLE);
  ngetchx();
}

void NewMap (void)
{
  DrawBox ("New Map");
}


En plus, le DrawStr marche mais pas les dessins de rectangle, 1/2h que je suis dessus et je comprends pas fou A priori c'est au niveau de Clip que ça déconne.
edit -> Bon les rectangle marchent (oublié extern sick), mais toujours le problème avec --remove-unused...

J'ai honte de poster ça, je sens que je vais me prendre le gros vent du débutant, mais yen a marre mad

No reproductible Please complete bug report, etc, etc, etc

221

Bon, je t'envoie un mail avec un snapshot.

222

http://www.siteduzero.com/tutoriel-3-14005-a-l-assaut-des-pointeurs.html

Pourquoi tous les tutos C montent toujours les pointeurs en épingle ? Ce sont que des histoires de registre d'adresse purée, faut arrêter triso

223

Parce que les gens qui viennent du BASIC ou qui n'ont rien programmé avant ne comprennent pas du tout ce que c'est.
avatar
Mes news pour calculatrices TI: Ti-Gen
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é

224

./222 > Heu, non ça a rien à voir avec une quelconque notion de registre, justement.
Ça fonctionne très bien sur une architecture entièrement basée sur la pile (cf. le CIL/MSIL par exemple).
Les pointeurs [en C] sont complètement liés avec la façon [qu'à le langage C] de représenter les variables en mémoire.
C'est une représentation concrète de la notion [abstraite] de référence. Là aussi ça pourrait être complètement différent et tout de même fonctionner sans accroc. (Voir les références en C++, ou en CIL/MSIL qui sont des implémentations différentes)

Et oui comme essaye de le dire Kevin dans le post d'après, tu ne peux comprendre les pointeurs que si tu as fait de l'assembleur ou que tu sais coder en C[++ ?], sinon ça sort pas comme ça d'un chapeau magique. C'est justement le problème du C (mais aussi un avantage) d'être trop proche du fonctionnement sous-jacent de la machine.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

225

Ah ok, je pensais pas que ça posait tant de problèmes que ça. Je dois mal me souvenir de mes difficultés avec les modes d'adressages et les déréférencement, mais à la réflexion, ça c'est sûrement pas fait tout seul, oui. happy

226

Lorsque je suis passé au C, ma seule difficulté était de savoir quand la variable correspondait à un An ou à un (An), en fait ^^
Mais c'est vrai que sur le 68k, il est assez facile de faire la conversion C non optimisé <---> 68k, je trouve. Avec une archi différente, ça serait sûrement différent.
Quand on a fait du 68k, on connaît bien le fonctionnement interne du C et le problème des adresses, ce qui n'est pas du tout le cas quand on a seulement des langages de plus haut niveau.
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

227

c'est clair que le 68k est un très bon processeur pour l'apprentissage des systèmes smile

228

Quelques autres questions, en vrac :

1.
Généralement, quelle conventions typographiques utilise-t-on pour les noms de fonction ?
Et pour les noms de variables ?

Je cherche pas les 42 variantes possibles, juste l'habitude générale qui fait qu'un autre codeur reconnait d'emblée les différents symboles dans un code. grin


2.
Pour mes variables qui seraient sensées être globales dans un programme assembleur, j'utilise en fait une structure fourre-tout dans main(), puis je passe le pointeur de la structure à toutes les fonctions qui auront besoin des différentes données, pour les lire et les modifier.
Est-ce une bonne ou une mauvaise idée ? J'en vois pas les conséquences à long terme en fait, mais parait que les variables globales saylemal, bien qu'évidemment ce soit la solution de facilité qui tende les bras ^^
Ce que je fais avec cette structure, c'est en fait ce que je fais en assembleur avec un registre qui pointe en permanence dans le stackframe contenant les variables accessibles à tout le monde (ce qui réduit la taille du binaire et évite le smc).

229

1. Gros troll incoming grin

Chaque codeur a ses propres conventions ; pour certains langages on considère que la convention utilisée pour les libs standards est "la bonne", mais je ne crois pas qu'il y ait vraiment une convention préférée pour le C.

2. Les mecs qui t'ont expliqué que les variables globales c'est mal sont les mêmes que ceux qui t'ont dit de ne jamais utiliser "goto". C'est mal uniquement quand on fait n'importe quoi avec, sinon on ne se serait pas fait chier à les inventer. Tu peux soit conserver une structure globale et ne pas te faire chier à la passer en paramètre partout (je crois qu'il y a moyen de réserver un registre pour elle si tu t'en sers vraiment souvent, mais je ne connais pas la syntaxe), soit la passer en paramètre à chacune de tes fonctions ; en 68k je ne sais pas du tout ce qui est le mieux en termes de performance.

D'un point de vue "architecture" j'aurais tendance à penser que la seconde solution est préférable, puisque ça ne repose pas sur le fait qu'une variable globale doit avoir été déclarée, tu gardes donc un peu plus d'autonomie au niveau de tes modules.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

230

Si un registre d'adresse était assigné à ma structure, ça serait idéal en fait.

231

(00:31:24) (Vertyos) Folco_ » http://tigcc.ticalc.org/doc/gnuexts.html#SEC98
(00:31:28) (Vertyos) You can define a global register variable in GNU C like this: (00:31:28) (Vertyos) register int *foo asm ("a3");
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

232

et ça powa, en tous cas pour ce qui est de l'optimisation taille.

En effet ça impose la contrainte globale que ce registre ne sert à rien d'autre et que par conséquent il n'a jamais besoin d'être restauré. Alors que si tu le passes juste en paramètre à toutes tes fonctions le compilateur risque de ne pas être sûr qu'il a été préservé, je crois (enfin peut-être pas, auquel cas ça reviendrait au même une fois compilé, je suis pas ŝur. Le truc c'est que pour passer des paramètres je crois qu'il utilise les registres en partant de a0, alors que pour une variable globale tu peux prendre a5 par exemple.)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

233

J'imagine bien, mais j'ai pris la résolution, dans un premier temps du moins, de ne plus m'occuper de registre, pour me discipliner un peu. grin

Vertyos m'a dit qu'en C, un void* était automatiquement casté vers n'importe quel autre type de pointeur, mais que c'était pas une bonne habitude de pas préciser le cast, entre autre à cause de langages comem C++.

L'inverse me semble vrai aussi, vous confirmez ? Passer un char* à une fonction qui réclame un void* ne semble pas problématique. Pareil, mieux vaut prendre l'habitude de caster quand même ?

234

non dans ce sens ça n'est pas un problème...

en fait l'idée c'est que ton pointeur a un type précis et que void* est juste le type de n'importe quel pointeur. (En termes techniques, char* par exemple est un sous-type de void*, c'est-à-dire que c'en est un cas particulier.)
Donc si ta fonction demande un void* ça veut dire qu'elle accepte n'importe quel pointeur. Pas besoin de cast qui ne ferait que brouiller le code (en gênant la lecture voire en supprimant un warning qui aurait pu être utile, par exemple).

Inversement, si tu récupères un pointeur qui a le type void*, ça veut dire que le compilateur sait juste que c'est un pointeur mais pas quel est son type précis : tu lui donnes donc une information en castant ce pointeur vers un type plus précis, tu lui dis : je sais que ce pointeur est un char*. Si tu n'explicites pas le cast, il va essayer de deviner le vrai type précis du pointeur à partir de l'usage que tu en fais, mais c'est pas forcément très clair.

En règle générale, c'est vrai aussi dans d'autres langages, tu peux toujours donner une valeur d'un sous-type (plus spécifique) quand on te demande une valeur d'un super-type (plus général), c'est complètement transparent et ça ne peut pas provoquer d'erreur¹.
Par contre caster une valeur dont le type connu est très général vers un sous-type plus spécifique devrait toujours être explicité, parce que si tu te trompes de type ça peut provoquer une erreur et que le compilateur ne peut pas vérifier. (Par exemple un short* a normalement toujours une valeur paire, mais pour un void* ça n'est bien sûr pas garanti, donc si tu utilises un void* là où un short* est attendu il y a une possibilité d'erreur. Si tu laisses le compilo faire un cast implicite cette possibilité risque de passer inaperçue.)

¹sauf en java avec les arrays parce que la relation de sous-typage est bugguée, mais bon dans un langage normal je veux dire tongue
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

235

Zephyr (./231) :
(00:31:24) (Vertyos) Folco_ » http://tigcc.ticalc.org/doc/gnuexts.html#SEC98
(00:31:28) (Vertyos) You can define a global register variable in GNU C like this:(00:31:28) (Vertyos) register int *foo asm ("a3");

Attention, si tu utilises ça, il faut sauvegarder la valeur dans une variable locale (ou une variable globale "classique") et la restaurer à la fin, sinon ton programme détruit le registre. sick

Sinon, la chose propre à faire, c'est de ne pas avoir une structure "toutes les variables" du tout (quelle horreur! sick), mais de passer exactement les variables qui servent aux fonctions qui les utilisent. Une fonction n'a pas à accéder à une variable qui ne lui appartient pas. Et en général, une fonction n'a pas à modifier les paramètres passés non plus (dans le cas où c'est nécessaire, il faut passer par la valeur de retour ou alors lui passer un pointeur). Un code qui mélange toutes les variables dans une structure globale, c'est un code de porcs! sick
avatar
Mes news pour calculatrices TI: Ti-Gen
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é

236

Une structure "toutes les variables" est le pattern architectural "mémoire partagée".
Avantage principal: son efficacité taille et vitesse, qui rend fréquente l'utilisation de ce pattern dans l'embarqué à fortes contraintes.
Défaut principal: sa mauvaise maintenabilité, à cause des effets de bord non triviaux entre fonctions.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

237

Kevin Kofler (./235) :
Un code qui mélange toutes les variables dans une structure globale, c'est un code de porcs! sick.gif
Mais non, c'est juste un code optimisé cheeky (mais en fait dans mon cas j'ai pas fait les accès à la structure explicitement mais à coup de #define ... sinon en effet c'est pas très lisible)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

238

Tout ce qu'explique Sally au ./234 est vrai pour les langages qui intègrent une notion de hiérarchie entre les types (cad généralement les langages objets), mais note quand même que cette conversion implicite de void* vers char* n'est valable qu'en C.

Je ne sais pas si le C considère que void* est le type générique de tous les pointeurs (pourquoi pas, je n'avais jamais entendu cette justification) mais ce n'est pas le cas du C++ qui te balancera une erreur "invalid conversion from 'void*' to 'plip*'" tant que tu n'ajouteras pas un transtypage explicite
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

239

Y a-t-il plus que deux niveaux de hiérarchie en C (void* et le reste), de toute façon ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

240

Non, c'est peut-être un cas particulier qui a été introduit par commodité et qui n'a pas pu être conservé avec le C++ qui impose
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)