明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 14651|回复: 27

[运行时] C#能调用autolisp的程序么?

  [复制链接]
发表于 2010-4-17 13:13:00 | 显示全部楼层 |阅读模式
  我想请问各位一个问题,我原来是用autolisp做二次开发的。现在改用c#,我有一些已经用autolisp写好的程序,我不想用c#重新改写啦,我想问下,能够用c#来调用那些程序么?
发表于 2019-10-19 10:19:36 | 显示全部楼层
本帖最后由 brainstorm 于 2019-10-19 10:23 编辑

autocad 2011以后版本用Application.Invoke(),这样就可以用lisp函数vlax-ldata取得图元的ldata了

Lisp

(vl-acad-defun 'lsptest1)
(defun lsptest1        (str)
  (list str "this is a test" "open the door" "sucess!" )
)

C#        
public static void Test()
        {
            var db = HostApplicationServices.WorkingDatabase;
            var doc = Application.DocumentManager.GetDocument(db);
            var ed = doc.Editor;
            //ResultBuffer rb = new ResultBuffer();
            
            ResultBuffer rb1 = new ResultBuffer
            {
                new TypedValue((int)LispDataType.Text, "lsptest1"),
                new TypedValue((int)LispDataType.Text, "this is a test too")
            };
            try
            {
                //var rb = InvokeArx.CallLispFunction(rb1);
                var rb = Application.Invoke(rb1);

                ed.WriteMessage("\n now is exporting what u need:" + rb.ToString());
            }
            catch(Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }

        }
发表于 2021-8-20 14:06:37 | 显示全部楼层
本帖最后由 guohq 于 2021-8-21 00:41 编辑

提前定义此函数
  1. (defun c:GetVariableValue(VarName)
  2.   (eval (read VarName))
  3.   )


就可以通过下面语句来获取Lisp变量的值了

  1. Application.Invoke(New ResultBuffer(New TypedValue(LispDataType.Text, "c:GetVariableValue"), New TypedValue(LispDataType.Text, Ed.GetString("变量名").StringResult)))


感兴趣的可以试试
发表于 2019-10-18 10:54:14 来自手机 | 显示全部楼层
提示无法找到名为acedinvoke 的入口点
发表于 2010-4-17 14:42:00 | 显示全部楼层
p/invoke acedInvoke
 楼主| 发表于 2010-4-17 15:43:00 | 显示全部楼层
感谢版主您的回答,不过,我看的不是太懂,我对C#不熟,能不能举个简单的例子。十分感谢
发表于 2010-4-17 16:14:00 | 显示全部楼层
本帖最后由 雪山飞狐_lzh 于 2011-1-28 15:36 编辑

1、声明lsp函数
(defun c:lsptest1() 2)
注意,最好以命令方式声明即C:XXX
如果非命令方式就要在lsp中调用vl-acad-defun函数
如:
(defun lsptest1() 2)
(vl-acad-defun 'lsptest1)
2、C#调用
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Reflection;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.DatabaseServices;
  9. using Autodesk.AutoCAD.ApplicationServices;
  10. using TlsCad.Collections;
  11. namespace TlsCad.Utils
  12. {
  13.     /// <summary>
  14.     /// 平台调用类
  15.     /// </summary>
  16.     public class InvokeArx
  17.     {
  18.         private static void AddValueToResultBuffer(ref ResultBuffer rb, object obj)
  19.         {
  20.             if (obj == null)
  21.             {
  22.                 rb.Add(new TypedValue((int)LispDataType.Text, ""));
  23.             }
  24.             else
  25.             {
  26.                 if (obj is string)
  27.                 {
  28.                     rb.Add(new TypedValue((int)LispDataType.Text, obj));
  29.                 }
  30.                 else if (obj is Point2d)
  31.                 {
  32.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  33.                     rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
  34.                 }
  35.                 else if (obj is Point3d)
  36.                 {
  37.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  38.                     rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
  39.                 }
  40.                 else if (obj is ObjectId)
  41.                 {
  42.                     rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
  43.                 }
  44.                 else if (obj is SelectionSet)
  45.                 {
  46.                     rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
  47.                 }
  48.                 else if (obj is double)
  49.                 {
  50.                     rb.Add(new TypedValue((int)LispDataType.Double, obj));
  51.                 }
  52.                 else if (obj is short)
  53.                 {
  54.                     rb.Add(new TypedValue((int)LispDataType.Int16, obj));
  55.                 }
  56.                 else if (obj is int)
  57.                 {
  58.                     rb.Add(new TypedValue((int)LispDataType.Int32, obj));
  59.                 }
  60.                 else if (obj is TypedValue)
  61.                 {
  62.                     rb.Add(obj);
  63.                 }
  64.             }
  65.         }
  66.         #region Redraw
  67.         [System.Security.SuppressUnmanagedCodeSecurity]
  68.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  69.         private static extern Int32 acedRedraw(long[] name, Int32 mode);
  70.         public static void Redraw()
  71.         {
  72.             acedRedraw(null, 1);
  73.         }
  74.         //[DllImport("acdb17.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
  75.         //private static extern int acdbGetAdsName(long[] name, ObjectId objId);
  76.         //public static void Redraw(ObjectId id)
  77.         //{
  78.         //    long[] adsname = new long[2];
  79.         //    acdbGetAdsName(adsname, id);
  80.         //    acedRedraw(adsname, 1);
  81.         //}
  82.         #endregion
  83.         #region TextScr
  84.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  85.         private static extern int acedTextScr();
  86.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  87.         private static extern int acedGraphScr();
  88.         public static bool DisplayTextScreen
  89.         {
  90.             set
  91.             {
  92.                 if (value)
  93.                     acedTextScr();
  94.                 else
  95.                     acedGraphScr();
  96.             }
  97.         }
  98.         #endregion
  99.         #region Command
  100.         /// <summary>
  101.         /// 控制命令行回显
  102.         /// </summary>
  103.         public static bool CmdEcho
  104.         {
  105.             get
  106.             {
  107.                 return (int)Application.GetSystemVariable("cmdecho") == 1;
  108.             }
  109.             set
  110.             {
  111.                 Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
  112.             }
  113.         }
  114.         [DllImport("acad.exe")]
  115.         private static extern int acedCmd(IntPtr vlist);
  116.                                     
  117.         /// <summary>
  118.         /// 调用AutoCad命令
  119.         /// </summary>
  120.         /// <param name="prompt">命令行提示</param>
  121.         /// <param name="arg">参数</param>
  122.         public static void Command(string prompt, object arg)
  123.         {
  124.             EdUtility.WriteMessage(prompt);
  125.             ResultBuffer rb = new ResultBuffer();
  126.             AddValueToResultBuffer(ref rb, arg);
  127.             try
  128.             {
  129.                 acedCmd(rb.UnmanagedObject);
  130.             }
  131.             catch { }
  132.             finally
  133.             {
  134.                 rb.Dispose();
  135.             }
  136.         }
  137.         /// <summary>
  138.         /// 调用AutoCad命令
  139.         /// </summary>
  140.         /// <param name="endCommandByUser">命令结束方式</param>
  141.         /// <param name="ldnode">参数</param>
  142.         public static void Command(bool endCommandByUser, ResultBuffer rb)
  143.         {
  144.             ResultBuffer rbend = new ResultBuffer();
  145.             try
  146.             {
  147.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  148.                 string currCmdName = doc.CommandInProgress;
  149.                 acedCmd(rb.UnmanagedObject);
  150.                 if (endCommandByUser)
  151.                 {
  152.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  153.                 }
  154.                 while (doc.CommandInProgress != currCmdName)
  155.                 {
  156.                     acedCmd(rbend.UnmanagedObject);
  157.                 }
  158.             }
  159.             catch { }
  160.             finally
  161.             {
  162.                 rb.Dispose();
  163.                 rbend.Dispose();
  164.             }
  165.         }
  166.         /// <summary>
  167.         /// 调用AutoCad命令
  168.         /// </summary>
  169.         /// <param name="endCommandByUser">命令结束方式</param>
  170.         /// <param name="args">参数</param>
  171.         public static void Command(bool endCommandByUser, params object[] args)
  172.         {
  173.             ResultBuffer rb = new ResultBuffer();
  174.             ResultBuffer rbend = new ResultBuffer();
  175.             foreach (object val in args)
  176.             {
  177.                 AddValueToResultBuffer(ref rb, val);
  178.             }
  179.             try
  180.             {
  181.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  182.                 string currCmdName = doc.CommandInProgress;
  183.                 acedCmd(rb.UnmanagedObject);
  184.                 if (endCommandByUser)
  185.                 {
  186.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  187.                 }
  188.                 while (doc.CommandInProgress != currCmdName)
  189.                 {
  190.                     acedCmd(rbend.UnmanagedObject);
  191.                 }
  192.             }
  193.             catch { }
  194.             finally
  195.             {
  196.                 rb.Dispose();
  197.                 rbend.Dispose();
  198.             }
  199.         }
  200.         #endregion
  201.         
  202.         #region Lisp
  203.         [System.Security.SuppressUnmanagedCodeSecurity]
  204.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  205.         extern static private int acedPutSym(string name, IntPtr result);
  206.         [System.Security.SuppressUnmanagedCodeSecurity]
  207.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  208.         extern static private int acedGetSym(string name, out IntPtr result);
  209.         [System.Security.SuppressUnmanagedCodeSecurity]
  210.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  211.         extern static private int acedInvoke(IntPtr args, out IntPtr result);
  212.         public static ResultBuffer CallLispFunction(ResultBuffer args)
  213.         {
  214.             IntPtr ip = IntPtr.Zero;
  215.             int st = acedInvoke(args.UnmanagedObject, out ip);
  216.             if (ip != IntPtr.Zero)
  217.             {
  218.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  219.                 return rbRes;
  220.             }
  221.             return null;
  222.         }
  223.         public static ResultBuffer CallLispFunction(string name, params object[] args)
  224.         {
  225.             ResultBuffer rbArgs = new ResultBuffer();
  226.             rbArgs.Add(new TypedValue((int)LispDataType.Text, name));
  227.             foreach (object val in args)
  228.             {
  229.                 AddValueToResultBuffer(ref rbArgs, val);
  230.             }
  231.             return CallLispFunction(rbArgs);
  232.         }
  233.                
  234.         internal static ResultBuffer GetLispSym(string name)
  235.         {
  236.             IntPtr ip = IntPtr.Zero;
  237.             acedGetSym(name, out ip);
  238.             if (ip != IntPtr.Zero)
  239.             {
  240.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  241.                 return rbRes;
  242.             }
  243.             return null;
  244.         }
  245.         #endregion
  246.     }
  247. }
3、例子:
  1.         [CommandMethod("tt")]
  2.         public static void Test()
  3.         {
  4.             var db = HostApplicationServices.WorkingDatabase;
  5.             var doc = Application.DocumentManager.GetDocument(db);
  6.             var ed = doc.Editor;
  7.             var rb = InvokeArx.CallLispFunction("C:lsptest1");
  8.             ed.WriteMessage("{0}", rb);
  9.         }
 楼主| 发表于 2010-4-17 17:16:00 | 显示全部楼层

十分感谢您。

不过,我调试了一下,这个程序好像有点点bug,一个就是

using TlsCad.Collections;

这个好像有问题,TlsCad下好像没有Collections

然后就是124行

EdUtility.WriteMessage(prompt);

这个EdUtility是属于哪个库的?当我把using TlsCad.Collections;这句注释掉,调试的时候显示不存在EdUtility。

请问是不是我少添加了什么引用?

发表于 2010-4-17 17:18:00 | 显示全部楼层

不是bug

EdUtility.WriteMessage相关的是我自己的库函数,呵呵

你可以用ed.WriteMessage去代替

发表于 2010-4-17 17:42:00 | 显示全部楼层

学习学习!

请教版主:能否判断Lisp函数是否存在呢?即是否已装载?

 楼主| 发表于 2010-4-17 17:47:00 | 显示全部楼层

您给的这个程序,我现在调通啦,很好用。

真的十分感谢您。

发表于 2010-4-17 19:34:00 | 显示全部楼层

能否判断Lisp函数是否存在呢?即是否已装载?

对调用Lisp方面研究的不太多,呵呵

以前搞Lisp的应该知道,比如飞诗、小狼。。。

不过这方面的应用建议作为过渡可以,完善的话还是代码全部移植到C#

 楼主| 发表于 2010-4-19 12:05:00 | 显示全部楼层

呵呵,这个还真没有想过,lisp程序加载的话,只能通过流程保证啦。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 05:02 , Processed in 0.173250 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表