Вызов лисп функции с передачей списка точечных пар

Автор Тема: Вызов лисп функции с передачей списка точечных пар  (Прочитано 7236 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Всем привет,
Можно ли вызвать лисп функцию и передать ей список точечных пар?
Передать нужно примерно такой список:
Код - Auto/Visual Lisp [Выбрать]
  1. (("Name" . "Test")("Length" . 1000))
Тестовый пример:
Код - C# [Выбрать]
  1.         [CommandMethod("TestInvoke")]
  2.         public void TestInvoke()
  3.         {
  4.             ResultBuffer rb = new ResultBuffer( new TypedValue[]
  5.                {
  6.                    new TypedValue((int)LispDataType.Text, "TestLispFunc"),
  7.                    new TypedValue((int)LispDataType.ListBegin),
  8.                    new TypedValue((int)LispDataType.ListBegin),
  9.                    new TypedValue((int)LispDataType.Text, "Name"),
  10.                    new TypedValue((int)LispDataType.Text, "Test"),
  11.                    new TypedValue((int)LispDataType.DottedPair),
  12.                    new TypedValue((int)LispDataType.ListBegin),
  13.                    new TypedValue((int)LispDataType.Text, "Length"),
  14.                    new TypedValue((int)LispDataType.Int32, "1000"),
  15.                    new TypedValue((int)LispDataType.DottedPair),
  16.                    new TypedValue((int)LispDataType.ListEnd)
  17.                }
  18.             );            
  19.             var res = Application.Invoke(rb);
  20.         }
Вызываемая лисп функция
Код - Auto/Visual Lisp [Выбрать]
  1. (defun TestLispFunc(p)
  2.         (princ p)              
  3. )
  4. (vl-acad-defun 'TestLispFunc)

В таком виде выводится ошибка:
Цитировать
Команда: TESTINVOKE
; ошибка: extra :LE element in reslist: (:LB :LB "Name" "Test" :DOTE :LB "Length" 1000 :DOTE :LE)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй окаймить его его еще в ListBegin/ListEnd, т.е. вместо
Код - Auto/Visual Lisp [Выбрать]
  1.     (("Name" . "Test")("Length" . 1000))
передавать
Код - Auto/Visual Lisp [Выбрать]
  1.     ((("Name" . "Test")("Length" . 1000)))
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Т.е. так?
Код - C# [Выбрать]
  1.                    new TypedValue((int)LispDataType.Text, "TestLispFunc"),
  2.                    new TypedValue((int)LispDataType.ListBegin),
  3.                    new TypedValue((int)LispDataType.ListBegin),
  4.                    new TypedValue((int)LispDataType.ListBegin),
  5.                    new TypedValue((int)LispDataType.Text, "Name"),
  6.                    new TypedValue((int)LispDataType.Text, "Test"),
  7.                    new TypedValue((int)LispDataType.DottedPair),
  8.                    new TypedValue((int)LispDataType.ListBegin),
  9.                    new TypedValue((int)LispDataType.Text, "Length"),
  10.                    new TypedValue((int)LispDataType.Int32, "1000"),
  11.                    new TypedValue((int)LispDataType.DottedPair),
  12.                    new TypedValue((int)LispDataType.ListEnd),
  13.                    new TypedValue((int)LispDataType.ListEnd)
Такой вывод:
Цитировать
Команда: TESTINVOKE
; ошибка: extra :LE element in reslist: (:LB :LB :LB "Name" "Test" :DOTE :LB "Length" 1000 :DOTE :LE :LE)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
А если убрать последний new TypedValue((int)LispDataType.ListEnd) ?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Убрал последний ListEnd
Код - C# [Выбрать]
  1.                    new TypedValue((int)LispDataType.Text, "TestLispFunc"),
  2.                    new TypedValue((int)LispDataType.ListBegin),
  3.                    new TypedValue((int)LispDataType.ListBegin),
  4.                    new TypedValue((int)LispDataType.ListBegin),
  5.                    new TypedValue((int)LispDataType.Text, "Name"),
  6.                    new TypedValue((int)LispDataType.Text, "Test"),
  7.                    new TypedValue((int)LispDataType.DottedPair),
  8.                    new TypedValue((int)LispDataType.ListBegin),
  9.                    new TypedValue((int)LispDataType.Text, "Length"),
  10.                    new TypedValue((int)LispDataType.Int32, "1000"),
  11.                    new TypedValue((int)LispDataType.DottedPair),
  12.                    new TypedValue((int)LispDataType.ListEnd)
Вывод:
Цитировать
Команда: TESTINVOKE
; ошибка: extra :LE element in reslist: (:LB :LB :LB "Name" "Test" :DOTE :LB "Length" 1000 :DOTE :LE)

Отмечено как Решение Вильдар 03-03-2016, 14:11:46

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1111
  • Карма: 173
Я, конечно, ни разу не спец по .NET, но, по-моему, сама структура создаваемого ResultBuffer какая-то "не та". Разве ListBegin и ListEnd не должны образовывать пары? Да и точечная пара, кажется, должна организовываться по принципу
Код - C# [Выбрать]
  1. rb.Add(new TypedValue((int)LispDataType.ListBegin));
  2. rb.Add(new TypedValue((int)LispDataType.Text, "Text"));
  3. rb.Add(new TypedValue((int)LispDataType.DottedPair));
  4. rb.Add(new TypedValue((int)LispDataType.Text, "Name"));
  5. rb.Add(new TypedValue((int)LispDataType.ListEnd));
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
Я, конечно, ни разу не спец по .NET, но, по-моему, сама структура создаваемого ResultBuffer какая-то "не та". Разве ListBegin и ListEnd не должны образовывать пары? Да и точечная пара, кажется, должна организовываться по принципу
Код - C# [Выбрать]
  1. rb.Add(new TypedValue((int)LispDataType.ListBegin));
  2. rb.Add(new TypedValue((int)LispDataType.Text, "Text"));
  3. rb.Add(new TypedValue((int)LispDataType.DottedPair));
  4. rb.Add(new TypedValue((int)LispDataType.Text, "Name"));
  5. rb.Add(new TypedValue((int)LispDataType.ListEnd));
Как ни странно, но ты прав, Лёша. :) Хотя в ObjectARX не так (и последовательность у vildar82 правильная). Честно говоря как они это сделали - ума не приложу. Зная как в ObjectARX мне бы в голову не пришло проверять то как ты написал (т.е. чисто лисповский вариант).

Работает вот такой код:

Код - C# [Выбрать]
  1. [CommandMethod("TestInvoke")]
  2. public void TestInvoke()
  3. {
  4.   ResultBuffer rb = new ResultBuffer(new TypedValue[]
  5.     {
  6.       new TypedValue((int)LispDataType.Text, "TestLispFunc"),
  7.       new TypedValue((int)LispDataType.ListBegin),
  8.       new TypedValue((int)LispDataType.ListBegin),
  9.       new TypedValue((int)LispDataType.Text, "Name"),
  10.       new TypedValue((int)LispDataType.DottedPair),
  11.       new TypedValue((int)LispDataType.Text, "Test"),
  12.       new TypedValue((int)LispDataType.ListEnd),
  13.       new TypedValue((int)LispDataType.ListBegin),
  14.       new TypedValue((int)LispDataType.Text, "Length"),
  15.       new TypedValue((int)LispDataType.DottedPair),
  16.       new TypedValue((int)LispDataType.Int16, 1000),
  17.       new TypedValue((int)LispDataType.ListEnd),
  18.       new TypedValue((int)LispDataType.ListEnd)
  19.     }
  20.   );
  21.   var res = Application.Invoke(rb);
  22. }

vildar82
Обрати внимание на отличие строки с число 1000 у меня в коде и у тебя.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Забавно, но это действительно похоже на какой-то баг через который таки работает. Если передать .Net лисп-функции точечную пару, то на входе получится синтаксис как у vildar82, у Алексея-же передается список "замаскированный" под пару. Интересно если вызвать таким образом, с аргументом точечной пары из двух строк, что-то типа:
Код - Auto/Visual Lisp [Выбрать]
  1. (defun test(x) (strcat (car x) (cdr x)))
Отработает?? - если да то "обход" найден.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13880
  • Карма: 1786
  • Рыцарь ObjectARX
  • Skype: rivilis
(defun test(x) (strcat (car x) (cdr x)))
Код - Auto/Visual Lisp [Выбрать]
  1. (defun test(x)
  2.   (print (strcat (car (car x)) " . " (cdr (car x))))
  3. )
  4. (vl-acad-defun 'test)

Код - C# [Выбрать]
  1. [CommandMethod("TestInv1")]
  2. public void TestInv1()
  3. {
  4.   ResultBuffer rb = new ResultBuffer(new TypedValue[]
  5.    {
  6.      new TypedValue((int)LispDataType.Text, "Test"),
  7.      new TypedValue((int)LispDataType.ListBegin),
  8.      new TypedValue((int)LispDataType.ListBegin),
  9.      new TypedValue((int)LispDataType.Text, "Name"),
  10.      new TypedValue((int)LispDataType.DottedPair),
  11.      new TypedValue((int)LispDataType.Text, "Test"),
  12.      new TypedValue((int)LispDataType.ListEnd),
  13.      new TypedValue((int)LispDataType.ListEnd)
  14.    }
  15.   );
  16.   var res = Application.Invoke(rb);
  17. }

Результат:

Команда: TESTINV1

"Name . Test"
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение