xuhawk 发表于 2010-4-17 13:13:00

C#能调用autolisp的程序么?

我想请问各位一个问题,我原来是用autolisp做二次开发的。现在改用c#,我有一些已经用autolisp写好的程序,我不想用c#重新改写啦,我想问下,能够用c#来调用那些程序么?

brainstorm 发表于 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);
            }

      }

guohq 发表于 2021-8-20 14:06:37

本帖最后由 guohq 于 2021-8-21 00:41 编辑

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

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

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

感兴趣的可以试试:lol

brainstorm 发表于 2019-10-18 10:54:14

提示无法找到名为acedinvoke 的入口点

雪山飞狐_lzh 发表于 2010-4-17 14:42:00

p/invoke acedInvoke

xuhawk 发表于 2010-4-17 15:43:00

感谢版主您的回答,不过,我看的不是太懂,我对C#不熟,能不能举个简单的例子。十分感谢

雪山飞狐_lzh 发表于 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#调用
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using TlsCad.Collections;
namespace TlsCad.Utils
{
    /// <summary>
    /// 平台调用类
    /// </summary>
    public class InvokeArx
    {
      private static void AddValueToResultBuffer(ref ResultBuffer rb, object obj)
      {
            if (obj == null)
            {
                rb.Add(new TypedValue((int)LispDataType.Text, ""));
            }
            else
            {
                if (obj is string)
                {
                  rb.Add(new TypedValue((int)LispDataType.Text, obj));
                }
                else if (obj is Point2d)
                {
                  rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
                  rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
                }
                else if (obj is Point3d)
                {
                  rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
                  rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
                }
                else if (obj is ObjectId)
                {
                  rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
                }
                else if (obj is SelectionSet)
                {
                  rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
                }
                else if (obj is double)
                {
                  rb.Add(new TypedValue((int)LispDataType.Double, obj));
                }
                else if (obj is short)
                {
                  rb.Add(new TypedValue((int)LispDataType.Int16, obj));
                }
                else if (obj is int)
                {
                  rb.Add(new TypedValue((int)LispDataType.Int32, obj));
                }
                else if (obj is TypedValue)
                {
                  rb.Add(obj);
                }
            }
      }
      #region Redraw
      
      
      private static extern Int32 acedRedraw(long[] name, Int32 mode);
      public static void Redraw()
      {
            acedRedraw(null, 1);
      }
      //
      //private static extern int acdbGetAdsName(long[] name, ObjectId objId);
      //public static void Redraw(ObjectId id)
      //{
      //    long[] adsname = new long;
      //    acdbGetAdsName(adsname, id);
      //    acedRedraw(adsname, 1);
      //}
      #endregion
      #region TextScr
      
      private static extern int acedTextScr();
      
      private static extern int acedGraphScr();
      public static bool DisplayTextScreen
      {
            set
            {
                if (value)
                  acedTextScr();
                else
                  acedGraphScr();
            }
      }
      #endregion
      #region Command
      /// <summary>
      /// 控制命令行回显
      /// </summary>
      public static bool CmdEcho
      {
            get
            {
                return (int)Application.GetSystemVariable("cmdecho") == 1;
            }
            set
            {
                Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
            }
      }
      
      private static extern int acedCmd(IntPtr vlist);
                                    
      /// <summary>
      /// 调用AutoCad命令
      /// </summary>
      /// <param name="prompt">命令行提示</param>
      /// <param name="arg">参数</param>
      public static void Command(string prompt, object arg)
      {
            EdUtility.WriteMessage(prompt);
            ResultBuffer rb = new ResultBuffer();
            AddValueToResultBuffer(ref rb, arg);
            try
            {
                acedCmd(rb.UnmanagedObject);
            }
            catch { }
            finally
            {
                rb.Dispose();
            }
      }
      /// <summary>
      /// 调用AutoCad命令
      /// </summary>
      /// <param name="endCommandByUser">命令结束方式</param>
      /// <param name="ldnode">参数</param>
      public static void Command(bool endCommandByUser, ResultBuffer rb)
      {
            ResultBuffer rbend = new ResultBuffer();
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                string currCmdName = doc.CommandInProgress;
                acedCmd(rb.UnmanagedObject);
                if (endCommandByUser)
                {
                  rbend.Add(new TypedValue((int)LispDataType.Text, "\\"));
                }
                while (doc.CommandInProgress != currCmdName)
                {
                  acedCmd(rbend.UnmanagedObject);
                }
            }
            catch { }
            finally
            {
                rb.Dispose();
                rbend.Dispose();
            }
      }
      /// <summary>
      /// 调用AutoCad命令
      /// </summary>
      /// <param name="endCommandByUser">命令结束方式</param>
      /// <param name="args">参数</param>
      public static void Command(bool endCommandByUser, params object[] args)
      {
            ResultBuffer rb = new ResultBuffer();
            ResultBuffer rbend = new ResultBuffer();
            foreach (object val in args)
            {
                AddValueToResultBuffer(ref rb, val);
            }
            try
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                string currCmdName = doc.CommandInProgress;
                acedCmd(rb.UnmanagedObject);
                if (endCommandByUser)
                {
                  rbend.Add(new TypedValue((int)LispDataType.Text, "\\"));
                }
                while (doc.CommandInProgress != currCmdName)
                {
                  acedCmd(rbend.UnmanagedObject);
                }
            }
            catch { }
            finally
            {
                rb.Dispose();
                rbend.Dispose();
            }
      }
      #endregion
      
      #region Lisp
      
      
      extern static private int acedPutSym(string name, IntPtr result);
      
      
      extern static private int acedGetSym(string name, out IntPtr result);
      
      
      extern static private int acedInvoke(IntPtr args, out IntPtr result);
      public static ResultBuffer CallLispFunction(ResultBuffer args)
      {
            IntPtr ip = IntPtr.Zero;
            int st = acedInvoke(args.UnmanagedObject, out ip);
            if (ip != IntPtr.Zero)
            {
                ResultBuffer rbRes = ResultBuffer.Create(ip, true);
                return rbRes;
            }
            return null;
      }
      public static ResultBuffer CallLispFunction(string name, params object[] args)
      {
            ResultBuffer rbArgs = new ResultBuffer();
            rbArgs.Add(new TypedValue((int)LispDataType.Text, name));
            foreach (object val in args)
            {
                AddValueToResultBuffer(ref rbArgs, val);
            }
            return CallLispFunction(rbArgs);
      }
               
      internal static ResultBuffer GetLispSym(string name)
      {
            IntPtr ip = IntPtr.Zero;
            acedGetSym(name, out ip);
            if (ip != IntPtr.Zero)
            {
                ResultBuffer rbRes = ResultBuffer.Create(ip, true);
                return rbRes;
            }
            return null;
      }
      #endregion
    }
}3、例子:
      
      public static void Test()
      {
            var db = HostApplicationServices.WorkingDatabase;
            var doc = Application.DocumentManager.GetDocument(db);
            var ed = doc.Editor;
            var rb = InvokeArx.CallLispFunction("C:lsptest1");
            ed.WriteMessage("{0}", rb);
      }

xuhawk 发表于 2010-4-17 17:16:00

<p>十分感谢您。</p><p>不过,我调试了一下,这个程序好像有点点bug,一个就是</p><p>using TlsCad.Collections;</p><p>这个好像有问题,TlsCad下好像没有Collections</p><p>然后就是124行</p><p>EdUtility.WriteMessage(prompt);</p><p>这个EdUtility是属于哪个库的?当我把using TlsCad.Collections;这句注释掉,调试的时候显示不存在EdUtility。</p><p>请问是不是我少添加了什么引用?</p>

雪山飞狐_lzh 发表于 2010-4-17 17:18:00

<p>不是bug</p><p>EdUtility.WriteMessage相关的是我自己的库函数,呵呵</p><p>你可以用ed.WriteMessage去代替</p>

sieben 发表于 2010-4-17 17:42:00

<p>学习学习!</p><p>请教版主:能否判断Lisp函数是否存在呢?即是否已装载?</p>

xuhawk 发表于 2010-4-17 17:47:00

<p>您给的这个程序,我现在调通啦,很好用。</p><p>真的十分感谢您。</p>

雪山飞狐_lzh 发表于 2010-4-17 19:34:00

<p>能否判断Lisp函数是否存在呢?即是否已装载?</p><p>对调用Lisp方面研究的不太多,呵呵</p><p>以前搞Lisp的应该知道,比如飞诗、小狼。。。</p><p>不过这方面的应用建议作为过渡可以,完善的话还是代码全部移植到C#</p>

xuhawk 发表于 2010-4-19 12:05:00

<p>呵呵,这个还真没有想过,lisp程序加载的话,只能通过流程保证啦。</p><p></p>
页: [1] 2 3
查看完整版本: C#能调用autolisp的程序么?