.NET中调用lisp代码的一个类

来源:互联网 发布:linux内核编程 编辑:程序博客网 时间:2024/06/06 08:29

从一个日本网站上找到的,原址为http://www1.harenet.ne.jp/~hanafusa/mt/memo/archives/000236.html。

如果你不想或不能用acedCmd或SendCommand等,试一下这个。它用的是VLAX方式,源码如下:

Using directives

namespace HLIB.Utils
{
  
/// <summary>
  
/// VisualLISPと通信。
  
/// (vl-load-com)を実行してないとだめ。
  
/// </summary>

  public class Lisp : IDisposable
  
{
    
private bool Disposed = false;
    
private object m_vlObj;
    
private object m_vlFunc;
    
private AcadApplication m_app;

    
/// <summary>
    
/// コンストラクタ
    
/// </summary>
    
/// <param name="acadApp">AutoCADアプリケーション</param>

    public Lisp ( AcadApplication acadApp )
    
{
      m_app 
= acadApp;
      
try {
        m_vlObj 
= acadApp.GetInterfaceObject( "VL.Application.16" );
        
object acDoc = GetProperty( m_vlObj, "ActiveDocument" );
        m_vlFunc 
= GetProperty( acDoc, "Functions" );
      }
 catch {
        AcEd.CommandLinePrompts.Message( 
" VLオブジェクトの取得に失敗しました." );
      }

    }


    
~Lisp ()
    
{
      Dispose();
    }


    
/// <summary>
    
/// VlApp によって使用されているリソースを開放します。
    
/// </summary>

    public void Dispose ()
    
{
      
if ( Disposed == false ) {
        m_vlFunc 
= null;
        m_vlObj 
= null;
        m_app 
= null;
        Disposed 
= true;
      }

    }


    
/// <summary>
    
/// COMオブジェクトからプロパティを取得します。
    
/// </summary>
    
/// <param name="obj">取得元のオブジェクト</param>
    
/// <param name="propName">プロパティ名</param>
    
/// <returns></returns>

    private object GetProperty ( object obj, string propName )
    
{
      
return obj.GetType().InvokeMember( propName,
        BindingFlags.GetProperty, 
null, obj, null );
    }


    
/// <summary>
    
/// COMオブジェクトからインデクサを取得します。
    
/// </summary>
    
/// <param name="obj">取得もとのオブジェクト</param>
    
/// <param name="index">インデックス名</param>
    
/// <returns></returns>

    private object GetIndexer ( object obj, string index )
    
{
      
return obj.GetType().InvokeMember( "Item",
        BindingFlags.GetProperty, 
null, obj, new object[] { index } );
    }


    
/// <summary>
    
/// LISP関数を呼び出し、結果を返します。
    
/// </summary>
    
/// <param name="funcName">LISP関数名</param>
    
/// <param name="args">引数</param>
    
/// <returns></returns>

    private object InvokeLispFunction ( string funcName, object[] args )
    
{
      
object sym = GetIndexer( m_vlFunc, funcName );
      
return sym.GetType().InvokeMember( "funcall",
        BindingFlags.InvokeMethod, 
null, sym, args );
    }


    
/// <summary>
    
/// LISP式を評価します。
    
/// </summary>
    
/// <param name="lispStatement">LISP式</param>
    
/// <returns></returns>

    public object Eval ( string lispStatement )
    
{
      
try {
        
object sym = InvokeLispFunction( "read"new object[] { lispStatement } );
        
return InvokeLispFunction( "eval"new object[] { sym } );
      }
 catch {
        AcEd.CommandLinePrompts.Message( 
" LISP式の評価に失敗しました." );
        
return null;
      }

    }


    
/// <summary>
    
/// LISP変数から値を取得します。
    
/// </summary>
    
/// <param name="symbolName">変数名</param>
    
/// <returns></returns>

    public object GetValue ( string symbolName )
    
{
      
try {
        
return Eval( symbolName );
      }
 catch {
        
return null;
      }

    }


    
/// <summary>
    
/// LISP変数に値を代入します。
    
/// </summary>
    
/// <param name="symbolName">変数名</param>
    
/// <param name="val"></param>

    public void SetValue ( string symbolName, object val )
    
{
      Eval( 
"(vl-load-com)" );
      Eval( 
"(defun translate-variant (data) (cond ((= (type data) 'list) (mapcar 'translate-variant data)) ((= (type data) 'variant) (translate-variant (vlax-variant-value data))) ((= (type data) 'safearray) (mapcar 'translate-variant (vlax-safearray->list data))) (t data)))" );
      Eval( 
"(setq " + symbolName + " (translate-variant " + val + "))" );
      Eval( 
"(setq translate-variant nil)" );
    }


    
/// <summary>
    
/// LISP変数にnilを代入します
    
/// </summary>
    
/// <param name="symbolName">変数名</param>

    public void SetSymbolsToNil ( params string[] symbolName )
    
{
      
for ( int i = 0; i < symbolName.Length; i++ ) {
        Eval( 
"(setq " + symbolName[ i ] + " nil)" );
      }

    }


    
/// <summary>
    
/// LISTをArrayListに変換します。
    
/// </summary>
    
/// <param name="symList">LISTの入った変数名</param>
    
/// <returns></returns>

    public ArrayList GetLispList ( string symList )
    
{
      ArrayList ret 
= new ArrayList();
      
object list;
      
long len;
      
try {
        list 
= Eval( symList );
        len 
= ( long )InvokeLispFunction( "length"new object[] { list } );
        
for ( long i = 0; i < len; i++ ) {
          ret.Add( InvokeLispFunction( 
"nth"new object[] { i, list } ) );
        }

      }
 catch {
      }

      
return ret;
    }


    
/// <summary>
    
/// DXFコードから情報を取得します。
    
/// </summary>
    
/// <param name="code">DXFコード</param>
    
/// <param name="symEname">図形名</param>
    
/// <returns></returns>

    private object getDxfData ( int code, object symEname )
    
{
      
object ent = InvokeLispFunction( "entget"new object[] { symEname } );
      
object val = InvokeLispFunction( "assoc"new object[] { code, ent } );
      
return InvokeLispFunction( "cdr"new object[] { val } );
    }


    
/// <summary>
    
/// LSIPの選択セットをAcadEntityの配列に変換します。
    
/// </summary>
    
/// <param name="symSS">選択セットの入っている変数名</param>
    
/// <param name="ents">AcadEntity配列の入れ物</param>
    
/// <returns></returns>

    public bool PickSetToSelectionSet ( string symSS, ref AcadEntity[] ents )
    
{
      
bool ret = false;
      
try {
        
object ss = Eval( symSS );
        
long sslength = ( long )InvokeLispFunction( "sslength"new object[] { ss } );
        ents 
= new AcadEntity[ sslength ];
        
for ( long i = 0; i < sslength; i++ ) {
          
object en = InvokeLispFunction( "ssname"new object[] { ss, i } );
          ents[ i ] 
= ( AcadEntity )( m_app.ActiveDocument.HandleToObject( ( string )getDxfData( 5, en ) ) );
        }

        ret 
= true;
      }
 catch {
      }

      
return ret;
    }


    
/// <summary>
    
/// LSIPの選択セットをActiveXの選択セットに変換します。
    
/// </summary>
    
/// <param name="symSS">選択セットの入っている変数名</param>
    
/// <param name="acadSS">AcadSelectionSetの入れ物</param>
    
/// <returns></returns>

    public bool PickSetToSelectionSet ( string symSS, ref AcadSelectionSet acadSS )
    
{
      
bool ret = false;
      acadSS.Clear();
      AcadEntity[] ents 
= null;
      
if ( PickSetToSelectionSet( symSS, ref ents ) ) {
        acadSS.AddItems( ents );
        ret 
= true;
      }

      
return ret;
    }


    
/// <summary>
    
/// LSIPの選択セットをObjectIdCollectionに変換します。
    
/// </summary>
    
/// <param name="symSS">選択セットの入っている変数名</param>
    
/// <param name="objIds">ObjectIdCollectionの入れ物</param>
    
/// <returns></returns>

    public bool PickSetToSelectionSet ( string symSS, ref AcDb.ObjectIdCollection objIds )
    
{
      
bool ret = false;
      objIds.Clear();
      AcadEntity[] ents 
= null;
      
if ( PickSetToSelectionSet( symSS, ref ents ) ) {
        
foreach ( AcadEntity en in ents ) {
          AcDb.ObjectId id 
= new AcDb.ObjectId();
          id.OldId 
= en.ObjectID;
          objIds.Add( id );
        }

        ret 
= true;
      }

      
return ret;
    }


    
/// <summary>
    
/// ObjectIdCollectionをLISPの選択セットに変換します。
    
/// </summary>
    
/// <param name="objIds">ObjectIdCollection</param>
    
/// <param name="symSS">選択セットを入れる変数名</param>
    
/// <returns></returns>

    public bool SelectionSetToPickSet ( AcDb.ObjectIdCollection objIds, string symSS )
    
{
      
bool ret = false;
      
try {
        Eval( 
"(setq " + symSS + " (ssadd))" );
        
foreach ( AcDb.ObjectId id in objIds )
          Eval( 
"(ssadd (handent "" + id.Handle + "")" + symSS + ")" );
        ret 
= true;
      }
 catch {
      }

      
return ret;
    }


    
/// <summary>
    
/// AcadSelectionSetをLISPの選択セットに変換します。
    
/// </summary>
    
/// <param name="acadDD">AcadSelectionSet</param>
    
/// <param name="symSS">選択セットを入れる変数名</param>
    
/// <returns></returns>

    public bool SelectionSetToPickSet ( AcadSelectionSet acadSS, string symSS )
    
{
      
bool ret = false;
      
try {
        Eval( 
"(setq " + symSS + " (ssadd))" );
        
foreach ( AcadEntity en in acadSS )
          Eval( 
"(ssadd (handent "" + en.Handle + "")" + symSS + ")" );
        ret 
= true;
      }
 catch {
      }

      
return ret;
    }

  }

}

原创粉丝点击