Тема: Вызов функции LISP из немодального блока диалога

Добрый день.
Вызываю функцию myfunc определенную в LISP.

int ret = ads_queueexpr(_T("(myfunc)"));

Функция myfunc выбирает примитивы и производит операции с ними, чертит результат. Диалоговое окно сворачивается. Почему-то функция начинает работать только после нажатия на ESC. Как сделать, чтобы работало без ESC.

Re: Вызов функции LISP из немодального блока диалога

Т. е. такое впечатление, что ads_queueexpr запихивает команду (myfunc) в нейкий буфер, а ESC выталкивает ее оттуда;)
Кто-нибудь обьяcнит происходящее, или как можно по-другому вызвать функцию LISP.

Re: Вызов функции LISP из немодального блока диалога

Эта функция посылает эту строку для исполнения в автокад. То есть строка исполняется как будто ее вызвали для исполнения вручную. В твоем случае нужно добавить пробел после закрывающей скобки и функция будет исплняться сразу. Но только в случае если автокад свободен. То есть у тебя нет гарантий что она исполнится сразу. Твоя строка будет
поставлена в очередь команд и будет исполнена когда дойдет очередь.
По другому вызвать лисп нельзя и более того автодеск обещал эту функцию исключить из будущих версий автокада.

Re: Вызов функции LISP из немодального блока диалога

Не работает, пробовал и пробел, и символ конца строки.

Re: Вызов функции LISP из немодального блока диалога

Работает вот так

acDocManager->sendStringToExecute(acDocManager->curDocument(), _T("(myfunc) "));

пробел обязателен. Если кто подскажет более элегантный способ, буду признателен.

Re: Вызов функции LISP из немодального блока диалога

Третий способ. Использовать объект VL.Application. Я его применял в коде Delphi, но вполне можно использовать и в VC.
Expression - LISP строка
Все остальные переменные OleVariant в Delphi.
VLispApp:=AcadApplication.GetInterfaceObject('VL.Application.16');
VLispDocument:=VLispApp.ActiveDocument;
VLispFunctions:=VLispDocument.Functions;
VLispEval:=VLispFunctions.Item['Eval'];
VLispRead:=VLispFunctions.Item['Read'];
VLispList:=VLispRead.FunCall(String(Expression));
VLispResult:=VLispEval.FunCall(VLispList);
Результат использования могу продемонстрировать в собственном приложении. См. ATable for AutoCAD http://www.alx.ncn.ru Когда вводите формулу для вычисления в ячейке, то она преобразуется в LISP и передается в движок описанный выше.

Re: Вызов функции LISP из немодального блока диалога

Вряд ли это более элегантный способ, но работает во всех версиях начиная с R14:
acedPostCommand("(myfunc) ");

Re: Вызов функции LISP из немодального блока диалога

> Alxd
Очень интересный подход - обратиться к VL. Решает, например, проблему с эхом от SendCommand в командной строке.
К сожалению в таком виде не все выражения, переданные через Expression выполняются корректно. Закономерности в сбоях пока уловить не удалось.

Re: Вызов функции LISP из немодального блока диалога

Попробуй окаймлять их:

(progn
...
)

Re: Вызов функции LISP из немодального блока диалога

> RAN
Обижаешь

Re: Вызов функции LISP из немодального блока диалога

Тогда покажи пример выражения, которое выполняется некорректно. Может чего и подскажем.
Фактически это вызов (eval (read "твое выражение")) Могут быть нюансы с кавычками ...

Re: Вызов функции LISP из немодального блока диалога

На самом деле есть "непонятная нестабильность". В совершенно непонятных случаях может генерироваться исключение. Delphi его обрабатывает нормально, но сам факт настораживает.
По сути дела, постоянно вызываются одни и теже стабильно вычисляемые функции. Но в какой-то неуловимый момент, скажем после 300-го выполнения, вдруг исключение! Можно и наплевать на него, просто настораживает.
Да! Еще VL вроде не поддерживает вызов интерактивных функций типа getpoint и т.п.

Re: Вызов функции LISP из немодального блока диалога

Alxd пишет:

Еще VL вроде не поддерживает вызов интерактивных функций типа getpoint

В том-то и дело, что в одних программах "поддерживает", а в других на get... (или где-то еще) выполнение прерывается, не доходя до конца. Закономерность не улавливается пока.

Re: Вызов функции LISP из немодального блока диалога

Я обнаружил еще одну особенность, но не знаю, относится ли она к VL.
Есть функция, написанная на ObjectARX и использующая ssget в коде. Если ее вызвать из VL, который находится в цикле запроса действий пользователя:
while (x)
{
  initget...
  getkword...
  VLExec(функция с ssget)
}
то после ее использования не срабатывают ключевые слова! Только ESC помогает выйти! Чушь какая-то. Пока ломаю голову, как обойти этот баг.

Re: Вызов функции LISP из немодального блока диалога

Утверждать не берусь, но очень похоже на то, что ресурсы неправильно переключены.

Re: Вызов функции LISP из немодального блока диалога

Очень похоже на то, что бродяги-программисты при реализации VL.Application проверяли только работу на элементарных функциях. Так сказать "продемонстрировали концепцию" и успокоились.

Re: Вызов функции LISP из немодального блока диалога

smile это очень похоже на Autodesk'овцев. Тем не менее попробуй перед вызовом VL.Application вызывать:

  HINSTANCE hAcad = acedGetAcadResourceInstance();
  HINSTANCE hCur  = AfxGetResourceHandle();
  AfxSetResourceHandle(hAcad);

А после вызова восстанавливать:

  AfxSetResourceHandle(hCur);

Достаточно часто помогает. Причем CAcModuleResourceOverride в этих ситуациях не спасает.

Re: Вызов функции LISP из немодального блока диалога

Еще один вариант вызова lisp-функции из arx-приложения (я когда-то постил его в autodesk.autocad.objectarx). Я не эспериментировал с возможностью использования этого варианта в немодальных окнах, но чем черт не шутит...

You can directly call lisp function from ObjectARX application using
acedInvoke(...).
See example:
=========LISP code start==============
(defun myfun()
  (setq myfunret 2)
)
;
; If you want to be able to invoke this function from an external ObjectARX
; application, you can use vl-acad-defun to make the function accessible.
;
(vl-acad-defun 'myfun)
=========LISP code end===============
=========C++ code start==============
int call_lisp_function(void)
{
    resbuf *rb_in = acutBuildList(RTSTR,"myfun",RTNONE);
    resbuf *rb_out = NULL;
    int rc = acedInvoke(rb_in,&rb_out);
    acutRelRb(rb_in); acutRelRb(rb_out);
    acedGetSym("myfunret",&rb_out);
    return (RSRSLT) ;
}
=========C++ code end===============

Re: Вызов функции LISP из немодального блока диалога

И еще один вариант для AutoCAD 2005-2006:

int acedEvaluateLisp(char const *, struct resbuf * &);

Re: Вызов функции LISP из немодального блока диалога

Функция acedEvaluateLisp() конечно интересная, но что-то уж очень медленно работает.

Re: Вызов функции LISP из немодального блока диалога

> VVV
За что купил - за то продал. smile