C#能调用autolisp的程序么?
我想请问各位一个问题,我原来是用autolisp做二次开发的。现在改用c#,我有一些已经用autolisp写好的程序,我不想用c#重新改写啦,我想问下,能够用c#来调用那些程序么? 本帖最后由 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-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
提示无法找到名为acedinvoke 的入口点 p/invoke acedInvoke 感谢版主您的回答,不过,我看的不是太懂,我对C#不熟,能不能举个简单的例子。十分感谢 本帖最后由 雪山飞狐_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);
} <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> <p>不是bug</p><p>EdUtility.WriteMessage相关的是我自己的库函数,呵呵</p><p>你可以用ed.WriteMessage去代替</p> <p>学习学习!</p><p>请教版主:能否判断Lisp函数是否存在呢?即是否已装载?</p> <p>您给的这个程序,我现在调通啦,很好用。</p><p>真的十分感谢您。</p> <p>能否判断Lisp函数是否存在呢?即是否已装载?</p><p>对调用Lisp方面研究的不太多,呵呵</p><p>以前搞Lisp的应该知道,比如飞诗、小狼。。。</p><p>不过这方面的应用建议作为过渡可以,完善的话还是代码全部移植到C#</p> <p>呵呵,这个还真没有想过,lisp程序加载的话,只能通过流程保证啦。</p><p></p>