Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Lemieux от 22-06-2023, 10:43:59

Название: Выполнение lisp скрипта в C# коде
Отправлено: Lemieux от 22-06-2023, 10:43:59
Всех приветствую. Возможно ли в коде C# выполнить lisp скрипт? И желательно скармливать не текстовый файл, а форматированную строку.
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: trir от 22-06-2023, 11:52:33
Document.SendStringToExecute?
https://www.theswamp.org/index.php?topic=33352.0
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: Привалов Дмитрий от 22-06-2023, 13:50:37
Возможно ли в коде C# выполнить lisp скрипт?

Если есть готовый скрипт, лучше выложить в файл, подгружать в Автокад.
Затем с помощью SendStringToExecute или Command вызывать функции Lisp или команды автокада.
https://adn-cis.org/forum/index.php?topic=8583.0


Можно сделать функцию лисп в C# и затем использовать в lisp.
https://kpblc.wordpress.com/2009/07/29/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-lisp-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8-%D0%BD%D0%B0-net/

Запускать целый скрипт lisp из C# выглядит немного странным решением, т.к. будет медленнее, ограниченно по возможностям.
Зачем если не секрет? Тестирование, защита?
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: Lemieux от 22-06-2023, 15:01:24
Запускать целый скрипт lisp из C# выглядит немного странным решением, т.к. будет медленнее, ограниченно по возможностям.
Зачем если не секрет? Тестирование, защита?
Я хочу написать абстракцию над созданием кабелей, чтобы у пользователя была возможность самому создавать "описания" нужных кабелей через интерфейс. Этот интерфейс заключал в себе не только описание сообщений, тип кабеля, но и возможность самому создать форматку по образцу и заполнять её во время вывода документации по проекту. А вот как раз заполнение я хотел перенести на плечи пользователя, с помощью написанного скрипта.
Описал как мог. Я думаю, что можно реализовать по другому, но мне сама задача интересна.
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: Александр Ривилис от 22-06-2023, 20:08:05
Возможно ли в коде C# выполнить lisp скрипт?
Да. Использовать или Application.Invoke или обертку над acedEvaluateLisp из ObjectARX. Это для синхронного выполнения lisp-кода. Ну а асинхронно можно и при помощи SendStringToExecute
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: Алексей Кулик от 22-06-2023, 21:47:16
Код - C# [Выбрать]
  1.    // Credits to Tony Tanzillo, Alexander Rivillis, Kerry Brown...
  2.  
  3.     /// <summary>
  4.     /// Provides methods to comunicate with AutoLISP.
  5.     /// </summary>
  6.     public class LispExtensions
  7.     {
  8.         [System.Security.SuppressUnmanagedCodeSecurity]
  9.         [DllImport("accore.dll", EntryPoint = "acedInvoke",
  10.                 CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  11.         extern static private int acedInvoke(IntPtr args, out IntPtr result);
  12.  
  13.         /// <summary>
  14.         /// Invoke a LISP function.
  15.         /// The LISP function must be defined as an external subroutine using the c: prefix or invoking vl-acad-defun.
  16.         /// This is no more mandatory since A2011 as the managed Application.Invoke() method wraps acedInvoke.
  17.         /// </summary>
  18.         /// <param name="args">The function name (string) following by the function arguments.</param>
  19.         /// <returns>The LISP function return value or null if failed.</returns>
  20.         public static ResultBuffer InvokeLisp(ResultBuffer args)
  21.         {
  22.             IntPtr ip = IntPtr.Zero;
  23.             int status = acedInvoke(args.UnmanagedObject, out ip);
  24.             if (status == (int)PromptStatus.OK && ip != IntPtr.Zero)
  25.                 return ResultBuffer.Create(ip, true);
  26.             return null;
  27.         }
  28.  
  29.         [System.Security.SuppressUnmanagedCodeSecurity]
  30.         [DllImport("accore.dll", EntryPoint = "acedPutSym",
  31.                 CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  32.         extern static private int acedPutSym(string args, IntPtr result);
  33.  
  34.         /// <summary>
  35.         /// Set a LISP variable value.
  36.         /// </summary>
  37.         /// <param name="name">The variable name.</param>
  38.         /// <param name="rb">The variable value</param>
  39.         public static void SetLispSym(string name, ResultBuffer rb)
  40.         {
  41.             acedPutSym(name, rb.UnmanagedObject);
  42.         }
  43.  
  44.         [System.Security.SuppressUnmanagedCodeSecurity]
  45.         [DllImport("accore.dll", EntryPoint = "acedGetSym",
  46.                 CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
  47.         extern static private int acedGetSym(string args, out IntPtr result);
  48.  
  49.         /// <summary>
  50.         /// Get a LISP variable value.
  51.         /// </summary>
  52.         /// <param name="name">The variable name.</param>
  53.         /// <returns>The variable value or null if failed.</returns>
  54.         public static ResultBuffer GetLispSym(string name)
  55.         {
  56.             IntPtr ip = IntPtr.Zero;
  57.             int status = acedGetSym(name, out ip);
  58.             if (status == (int)PromptStatus.OK && ip != IntPtr.Zero)
  59.             {
  60.                 return ResultBuffer.Create(ip, true);
  61.             }
  62.             return null;
  63.         }
  64.     }
Пример использования:
Код - C# [Выбрать]
  1.        public void RunLispWithDottedPair(string LispFunctionName, Dictionary<string, string> LispArguments)
  2.         {
  3.             ResultBuffer rb = new ResultBuffer();
  4.             rb.Add(new TypedValue((int)LispDataType.Text, LispFunctionName));
  5.             rb.Add(new TypedValue((int)LispDataType.ListBegin));
  6.  
  7.             foreach (KeyValuePair<string, string> pair in LispArguments)
  8.             {
  9.                 rb.Add(new TypedValue((int)LispDataType.ListBegin));
  10.                 rb.Add(new TypedValue((int)LispDataType.Text, pair.Key));
  11.                 rb.Add(new TypedValue((int)LispDataType.DottedPair));
  12.                 rb.Add(new TypedValue((int)LispDataType.Text, pair.Value));
  13.                 rb.Add(new TypedValue((int)LispDataType.ListEnd));
  14.             }
  15.             rb.Add(new TypedValue((int)LispDataType.ListEnd));
  16.  
  17.             LispExtensions.InvokeLisp(rb);
  18.         }
Такое не покатит?
Название: Re: Выполнение lisp скрипта в C# коде
Отправлено: Lemieux от 23-06-2023, 15:23:03
Всем спасибо, скормил строку вот такого типа "(setq lmxSS (ssget \"_X\" '((0 . \"INSERT\") (2 . \"A3_Form_*\"))))\r\n(print (strcat \"Количество листов - \" (itoa (sslength lmxSS))))" в acedEvaluateLisp и всё заработало.