Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
20 mai 2015 3 20 /05 /mai /2015 16:14
Gérer la migration de vos applications lisp vers la version 2015 (VVC: Internal Error)

 

VVC: Internal Error, vous avez eu ce message ?

Si oui, il s’agit certainement d’un problème lié à l’utilisation de command dans un lisp

Depuis la version 2015, la commande lisp command n’est pas recommandée … (3 points d’un coup !)

Gile avait fait un article la dessus :  Compatibilité 2015

Et on peut également regarder ce sujet : problème avec command à partir de error

Il faut également consulter l’aide autocad à ce sujet

En gros : il faut remplacer command par command-s, surtout lorsque command est utilisé dans *error*, ou lorsque command est utilisé dans un mapcar, et command-s n’accepte pas les pause

Nous allons voir que ce n’est pas si simple

Chronologie du problème :
  •           Autocad 2012 : apparition de command-s, qui provoque un crash lorsqu’on l’utilise
  •           Autocad 2013 : command-s et command fonctionnent tous les 2
  •           Autocad 2014 : Idem 2013
  •           Autocad 2015 : command ne fonctionne plus de la même façon qu'auparavant.
  •           Autocad 2016 : idem 2015
Décryptage, analyse et perte de repères

Toutes ces affirmations citées plus haut doivent être soigneusement contrôlées et testées, car elles sont en générales incomplètes ou parfois inexacte :

Command ne marche pas avec mapcar

Pas toujours :

L’exemple de Gile

(mapcar

  '(lambda (c r) (command "_.circle" "_non" c r))

  '((0 0) (24 0) (36 0) (42 0) (45 0))

  '(16 8 4 2 1)

)

Ne marche pas avec la 2015, par contre :

(command "_line" "0,0")(mapcar 'command '("2,2" "3,3"))(command "")

Fonctionne très bien

La différence ?  dans l’exemple de Gile, chaque évaluation de mapcar achève la commande,

Dans le deuxième exemple,  mapcar est utilisé par paresse pour passer des arguments à une commande déjà commencée

Command-s  n’accepte pas les pause

 

L’aide Autocad  contient des inexactitudes :

(command-s "_line" "0,0" PAUSE "") est bien valide.

Par contre, effectivement,

(command-s "_line")

(command-s "2,2" "12.25,9" "")

Ne marche pas

C’est donc assez grave, car qui n’a pas, dans ses lisps, un truc du genre :

(command "_line" "0,0")

(while (= 1 (getvar "cmdactive"))

(command pause)

)

Bien sur, cela peut se remplacer par :

(command-s "_line" "0,0")

 

Car command-s accepte les pause, mais n’en a pas besoin :

La preuve :

(command-s "_line" "0,0")(prompt ”terminé")-> terminénil

VL-CMDF est il l’équivalent de command-s ?

L’aide LISP explique que le vl-cmdf était l'équivalent de command-s, obligeant à donner tous les arguments dès le début , mais en fait vl-cmdf est un mix entre command et command-s, et ne fonctionne pas toujours, mais parfois …

 

Existe-t-il d’autre cas d’erreur ?

On peut voir ce sujet : problème avec vl-cmdf et mapcar

Et l’explication de Gile montre qu’il y a un lien entre eval et mapcar, or j’ai eu des erreur avec un  (command  « _redraw ») à l’interieur  d’un eval

Que faire ?

Si on écoute Autodesk, il faudrait remplacer command par command-s

Or ce n’est pas si simple :

Si on veut gérer les versions, on a 3 cas : avant, 2012 et après

Command-s ne permet pas de faire les mêmes choses que command (par exemple l’appel séquentiel)

Donc un mise a niveau peut engendrer de longues heure de migration.

La méthode G-EAUX

Devant l’ampleur de la tâche, j’ai essayé de gruger

C’est un sujet de the swamp qui m’a donné l’idée de la redéfinition de command en command-s

Le problème, command est protégé, donc il faut utiliser pragma

Autre problème, pragma ne fonctionne pas s’il est directement appelé par acaddoc.lsp, il faut le mettre dans s ::startup

Redéfinir command par command-s

Donc voilà ce que j’ai mis dans mon acaddoc.lsp :

;;gestion du problème command-s, s'effectue après l'ouverture du dessin

(defun command-s-check ( / acadApp)

  (if (> (atof (getvar "ACADVER")) 18.2) ;_la 2012 ou command-s est apparu, mais ne fonctionne pas

    (progn

      (pragma '((unprotect-assign

             (setq acadApp (vlax-get-acad-object))   

             (vla-get-activedocument acadApp)

             command

            )

             )

      )

      (if (setq command command-s)

      (prompt "\nFunction Command redefined as command-s")

      )

    )

  )

)

 ;;Section ci dessous corrigée le 12/05/2016, il manquait le () du defun-q

(if s::startup

  (setq s::startup (append s::startup '((command-s-check))))

  (defun-q s::startup ()

         (mapcar 'eval '((command-s-check)))

  )

)

Un petit test :

Commande: !command

#<SUBR @000000002cea28a8 COMMAND-S>

Le miracle

J’ai fait tout ça par tâtonnement et je n’aurai pas choisi cette voie si j’avais su tout ce que je sais maintenant, mais  contre toute attente :,

(command "_line")

(command "2,2" "12.25,9" "")

Fonctionne très bien,  ainsi que :

(command "_line" "0,0")

(while (= 1 (getvar "cmdactive"))

(command pause)

)

Il n’y donc que les mapcar façons Gile à reprendre : Miracle !

Le Hic

Il reste un petit problème :

Si l’éditeur visual lisp est actif, la fonction unprotect-assign ne marche pas, on a un message pour entrer dans une boucle d’arrêt, il faut répondre non

Ceci était vrai en mai, mais il y a du nouveau :

 La solution dans la partie II de l'article ...

G-EAUX

 

 

Partager cet article
Repost0

commentaires