National Instruments
ldci22-Feb-2013/13:32:36+1:00
Bonjour
Ceux qui suivent le développement de Red savent que j'ai porté le driver permettant d'accéder aux cartes d'acquisition de National Instruments. J'en ai profité pour mettre à jour la version REBOL 2 http://www.wuala.com/fjouen/Code/NI/REBOL/
Bien sûr, il vous faut un système NI pour que cela fonctionne. Néanmoins, le code est intéressant à regarder (demo.r) pour quelques astuces concernant les bibliothèques externes.

Quand REBOL 3 sera stabilisé (notamment avec un GUI efficace) je me pencherai sur cette version. L'intérêt pour moi de passer par la lib de NI est de m'éviter de passer par Labview pour le recueil des données et la gestion des interfaces.
ldci10-Mar-2013/17:23:23+1:00
Pourquoi Red est il génial ?
Toujours en amusant avec les systèmes National Instruments, je découvre toutes les facettes de Red et de Red/System. Red a une gestion des pointeurs qui est grandiose.

Exemple:
    int: 0
    pint: declare pointer![integer!] ; 
    pint: :int ; adresse de l'entier: on pointe sur l'entier
    
    print ["Valeur de la variable : " int lf]
    print ["Adresse de la variable: " pint lf]
    print ["Contenu du pointeur : " pint/value lf]


Bon , ça c'était facile. Maintenant imaginons que nous voulons utiliser un pointeur sur un tableau de réels (float readArray [] en C).


Tout est dans allocate qui permet de réserver l'espace mémoire et dans l'arithmétique des pointeurs qui permet de se déplacer dans le tableau!

Exemple;


    arraySize: 8 * size? float!; la taille pour un tableau de 8 réels
    pmem: allocate arraySize ; on reserve la mémoire pour le tableau 
    *data: declare pointer! [float!] 
    *data: as  [pointer! [float!]] pmem ; on crée le pointeur qui pointe sur la zone mémoire allouée
 
     c: 1
    while [c < 9] [
        print [c ": " *data/c lf] ; on accede à chacune des 8 valeurs :même chose que *data: *data + 1 print *data/value  
        c: c + 1
    ]
   free pmem ; libère la zone allouée


C'est pas joli ? On reste dans l'élégance et la concision de REBOL avec la puissance du C
En tout cas, j'adore!
PierreCh10-Mar-2013/23:25:51+1:00
Merci du témoignage! Je n'ai pas encore réussi à sauter le pas et coder en Red et Red/System, mais ceci m'a mis l'eau à la bouche!
DocKimbel10-Mar-2013/23:29:37+1:00
Content que ça te plaise François !

Juste une précision, la ligne *data: declare pointer! [float!] est optionelle, le compilateur est capable d'inférer le type d'après la 1ère affectation (sauf dans le cas où la valeur affectée est null).

Bon coding !
ldci12-Mar-2013/23:11+1:00
Bon
Je continue à explorer Red/System.
Aujourd'hui les macros que Doc nous propose gentiment
Quelque chose de simple en c puis en red
#define MAX(a,b)         ((a < b) ?  (b) : (a)) ; en C
#define MAX (a b) (either a < b [b][a]); en red/S  ça fonctionne très bien


Un peu plus compliqué maintenant
[code]
#define BIGGEST(a,b,c) ((MAX(a,b) < c) ? (c) : (MAX(a,b))) ; en C
#define BIGGEST (a b c) (either MAX (a b) < c [c][MAX (a b)]); en red/S ne fonctionne pas

/code]
exemple
print [MAX (10 15) lf] -> 15
print [ BIGGEST (10 20 30) lf]
le second appel à MAX (a b) dans BIGGEST renvoie Compilation Error: parens are only allowed nested in an expression
c'est surprenant car la substitution de la macro semble fonctionner : (either 10 < 20 [15] [10])


Qui aurait une idée lumineuse?
ldci12-Mar-2013/23:35:19+1:00
zut
j'ai oublié une balise

#define BIGGEST(a,b,c) ((MAX(a,b) < c) ? (c) : (MAX(a,b))) ; en C
#define BIGGEST (a b c) (either MAX (a b) < c [c][MAX (a b)]); en red/S ne fonctionne pas 



C'est mieux.
Bon pour résoudre le pb on peut toujours passer par une fonction
Biggest: func [a [integer!] b [integer!] c [integer!] return: [integer!] /local val ] [
    val: MAX (a b)
    either val < c [c] [val]
]


Cela fonctionne, mais on perd l'intérêt de la macro et des paramètres formels qui ne demandent pas de spécifier le type des variables.
On peut tout à fait avec une macro écrire MAX (p+q r+s). Bon on peut pas tout avoir.
DocKimbel13-Mar-2013/3:30:24+1:00
Salut François,

Le code suivant fonctionne:
	#define _MAX (a b) (either a < b [b][a])
	#define BIGGEST (a b c) (either _MAX (a b) < c [c][0 + _MAX (a b)])
	
	print [ BIGGEST (10 20 30) lf]


renvoit bien ici : 30

Les différents points à noter:

1) Red/System ne permet pas d'utiliser une expression entre parenthèses seules, c'est un effet de bord d'une limitation concernant les parenthèses, mais je peux peut-être la lever (je vais regarder). Donc pour la contourner, j'inclus l'expression entre parenthèse seule dans une autre expression qui ne change pas sa valeur: 0 + ...

2) L'identifiant MAX est déjà utilisé dans la librairie standard de Red (je n'ai pas testé avec le compilo Red/System seul), j'ai donc utilisé _MAX pour rendre l'indentifiant unique.

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2