Тема: LISP.Как вызвать функцию документа из отдельного именного пространства VLX-модуля.

Определяем функцию-посредник в пространстве документа и регистрируем её:

(defun InvokeBroker()
  (setq InvokeArgsOrReturn (vl-catch-all-apply (function (lambda () (apply (car InvokeArgsOrReturn) (cdr InvokeArgsOrReturn))))))
);
(vl-acad-defun 'InvokeBroker)

VLX-модуль с отдельным именным пространством должен содержать инструкцию импорта:

(vl-arx-import 'InvokeBroker)

и код, создающий функцию-оболочку для удобной работы:

(defun DocumentInvoke (subr args)
  (vl-doc-set 'InvokeArgsOrReturn (cons subr args))
  (InvokeBroker)
  (vl-catch-all-apply 'vl-doc-ref (list 'InvokeArgsOrReturn))
);

Вот и всё.
*** Пример вызова функции, определенной в пространстве документа, из VLX-модуля с отдельным именным пространством ***
Форма вызова полностью совпадает с вызовом стандартной AutoLISP-функции apply:

(setq res (DocumentInvoke 'somefun (list arg1 arg2)))

где somefun - определенная с помощью defun функция пространства документа, получающая два аргумента.
В переменную res будет помещено возвращаемое значение функции somefun.
Предложенная техника позволяет передавать в функцию документа в качестве аргументов и возвращать из неё
в именное пространство VLX-модуля практически любые используемые в VisualLISP типы данных, кроме переменных,
тип которых определяется, как USUBR, SUBR и EXRXSUBR.
Функция DocumentInvoke не генерирует исключений. В случае ошибки в имени вызываемой функции, в количестве или типах
передаваемых аргументов, или в случае каких-либо непредвиденных исключений внутри вызываемой функции
возвращает объект  #<%catch-all-apply-error%>.

Re: LISP.Как вызвать функцию документа из отдельного именного пространства VLX-модуля.

В ACAD 2008 наткнулся на новое в поведении функций vl-doc-set и vl-doc-ref.
Проблема состоит в том, что они отказываются писать и читать объект исключения #<%catch-all-apply-error%> и генерируют маловразумительное исключение:

; error: no function definition: variantp

Возможно именно так эти функции вели себя и раньше, просто я недостаточно их тестировал.
Проверить сейчас нет возможности.
Кому не сложно, выполните пожалуйста из ком. строки

(vl-doc-set 'assa (vl-catch-all-apply '/ '(1 0))) 

в версиях до 2008 и скажите, что получилось.

Применительно к основной теме, чтобы не зависеть от этого нюанса, следует функцию InvokeBroker определять без перехватчика ошибок:

(defun InvokeBroker()
  (setq InvokeArgsOrReturn (apply (car InvokeArgsOrReturn) (cdr InvokeArgsOrReturn)))
);

а перехват возможных исключений проводить в пространстве VLX-модуля, просто упаковывая вызов DocumentInvoke в конструкцию vl-catch-all-apply.

Re: LISP.Как вызвать функцию документа из отдельного именного пространства VLX-модуля.

AutoCAD 2006 RUS SP1.

Команда: (vl-doc-set 'assa (vl-catch-all-apply '/ '(1 0)))
#<%catch-all-apply-error%>

Re: LISP.Как вызвать функцию документа из отдельного именного пространства VLX-модуля.

Спасибо, Владимир.
Так вот, тихой сапой. Сегодня функция возвращает одно, завта - другое... Ладно бы другое. Возвращает сбой!
В одном старом советском фильме герой Евгения Леонова говорил что-то вроде: "Должен вас предупредить. Со мной дело иметь невозможно." Кто бы мог подумать, что это про Автодеск.