乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 149|回复: 9

Lisp与.NET互相调用。CAD2008 .net程序运行出现异常,请各位老师找出出错原因,非...

[复制链接]

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2015-10-12 13:43:00 | 显示全部楼层 |阅读模式
李冠亿老师《深入浅出.NET二次开发》中6.8.3章节经出了一个Lisp与.NET程序互相调用的例子,如下:
/////////////////////////////////////////////////////////////////////////////////////////////////
//http://www.bimcad.org 数字建筑
//深入浅出AutoCAD二次开发(李冠亿)
/////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using System.Runtime.InteropServices;
[assembly: CommandClass(typeof(Sample.CH6_8_3))]
namespace Sample
{
    class CH6_8_3
    {
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedInvoke")]
        private static extern int acedInvoke(IntPtr args, out IntPtr result);
        public static ResultBuffer InvokeLisp(ResultBuffer args, ref int stat)
        {
            IntPtr rb = IntPtr.Zero;
            stat = acedInvoke(args.UnmanagedObject, out rb);
            if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
                return (ResultBuffer)DisposableWrapper.Create(typeof(ResultBuffer), rb, true);
            return null;
        }
        [CommandMethod("CallLispFunction")]
        public void CallLispFunction()
        {
            ResultBuffer args = new ResultBuffer();
            int stat = 0;
            args.Add(new TypedValue((int)LispDataType.Text, "c:CallByNet"));
            ResultBuffer res = InvokeLisp(args, ref stat);
        }
        [LispFunction("CallByLispFunction")]
        public static void CallByLispFunction(ResultBuffer rbArgs)
        {
            foreach (TypedValue rb in rbArgs)
                if (rb.TypeCode == (int)Autodesk.AutoCAD.Runtime.LispDataType.Text)
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(rb.Value.ToString());
        }
    }
}
并给出了对应的lisp文件的代码:
(defun c:CallByNet()
(setq p1 (getpoint"输入第一点:"))
(setq p2 (getpoint"输入第二点:"))
(command "line" p1 p2 "")
)
(defun c:CallNet()
(setq t1 "BimCad.org")
(setq t2 "数字建筑")
(CallByLispFunction t1 t2)
)
我在测试过程中发现.NET调用lisp的函数Calllispfunction可正常运行,但使用lisp调用.NET的CallNET命令出现异常,错误如下:
命令: callnet
System.ArgumentException: 绑定到目标方法时出错。
   在 System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo
method, Boolean throwOnBindFailure)
   在 AcMgCommandClass.InvokeWorker(AcMgCommandClass* , MethodInfo mi, Object
commandObject, Boolean bLispFunction)
   在 AcMgCommandClass.InvokeWorkerWithExceptionFilter(AcMgCommandClass* ,
MethodInfo mi, Object commandObject, Boolean bLispFunction)
   在 AcMgCommandClass.Invoke(AcMgCommandClass* ,
gcroot* mi, Boolean bLispFunction)
   在 AcMgCommandClass.CommandThunk.InvokeLisp(CommandThunk* ); 错误: ADS 请求错误
原以为是CAD2008安装过程中出现的msxml6.dll不能更新的错误,但重装系统及下载微软msxml6_x86(1.3M)修复后也是同样的错误,经网友确认CAD2011、2014下可正确运行,也说明李老师给的代码是可行的,但现在我的电脑上出现上面的错误,导致程序不能正常运行,请各位指点一下如何才能用Lisp调用.NET的函数。
本人运行环境如下:GHOST XP(32位)SP3,CAD2008(32位),
回复

使用道具 举报

0

主题

275

帖子

8

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
275
发表于 2015-10-12 18:19:00 | 显示全部楼层
为什么这样用!
回复

使用道具 举报

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2015-10-13 08:56:00 | 显示全部楼层

请教如何用才对?
回复

使用道具 举报

0

主题

275

帖子

8

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
275
发表于 2015-10-13 10:13:00 | 显示全部楼层

class CH6_8_3 用 public class CH6_8_3
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using System.Runtime.InteropServices;
[assembly: ExtensionApplication(typeof(Sample.MyPlugin))]
[assembly: CommandClass(typeof(Sample.CH6_8_3))]
namespace Sample
{
    public class MyPlugin : IExtensionApplication
    {
        void IExtensionApplication.Initialize()
        {
           
        }
        void IExtensionApplication.Terminate()
        {
            
        }
    }
    public class CH6_8_3
    {
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedInvoke")]
        private static extern int acedInvoke(IntPtr args, out IntPtr result);
        public static ResultBuffer InvokeLisp(ResultBuffer args, ref int stat)
        {
            IntPtr rb = IntPtr.Zero;
            stat = acedInvoke(args.UnmanagedObject, out rb);
            if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
                return (ResultBuffer)DisposableWrapper.Create(typeof(ResultBuffer), rb, true);
            return null;
        }
        [CommandMethod("CallLispFunction")]
        public void CallLispFunction()
        {
            ResultBuffer args = new ResultBuffer();
            int stat = 0;
            args.Add(new TypedValue((int)LispDataType.Text, "c:CallByNet"));
            ResultBuffer res = InvokeLisp(args, ref stat);
        }
        [LispFunction("CallByLispFunction")]
        public static void CallByLispFunction(ResultBuffer rbArgs)
        {
            foreach (TypedValue rb in rbArgs)
                if (rb.TypeCode == (int)Autodesk.AutoCAD.Runtime.LispDataType.Text)
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(rb.Value.ToString());
        }
    }
}
回复

使用道具 举报

14

主题

404

帖子

13

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
455
发表于 2015-10-13 15:43:00 | 显示全部楼层
在XP 、CAD2007能运行。
回复

使用道具 举报

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2015-10-13 15:52:00 | 显示全部楼层

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using System.Runtime.InteropServices;
[assembly: ExtensionApplication(typeof(Lisp2NET.MyPlugin))]
[assembly: CommandClass(typeof(Lisp2NET.CH6_8_3))]
namespace Lisp2NET
{
    public class MyPlugin : IExtensionApplication
    {
        void IExtensionApplication.Initialize()
        {
           
        }
        void IExtensionApplication.Terminate()
        {
            
        }
    }
    class CH6_8_3
    {
        [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedInvoke")]
        private static extern int acedInvoke(IntPtr args, out IntPtr result);
        public static ResultBuffer InvokeLisp(ResultBuffer args, ref int stat)
        {
            IntPtr rb = IntPtr.Zero;
            stat = acedInvoke(args.UnmanagedObject, out rb);
            if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
                return (ResultBuffer)DisposableWrapper.Create(typeof(ResultBuffer), rb, true);
            return null;
        }
        [CommandMethod("CallLispFunction")]
        public void CallLispFunction()
        {
            ResultBuffer args = new ResultBuffer();
            int stat = 0;
            args.Add(new TypedValue((int)LispDataType.Text, "c:CallByNet"));
            ResultBuffer res = InvokeLisp(args, ref stat);
        }
        [LispFunction("CallByLispFunction")]
        public static string  CallByLispFunction(ResultBuffer rbArgs)
        {
            foreach (TypedValue rb in rbArgs)
                if (rb.TypeCode == (int)Autodesk.AutoCAD.Runtime.LispDataType.Text)
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(rb.Value.ToString());
            return "";
        }
    }
}
以上修改源于EDATA,指明CAD2008时函数返回值不能空(lisp函数至少会返回一个nil)
XP SP3 CAD2008 sp1 VS2010 .net 2.0下测试通过,谢谢EDATA!
回复

使用道具 举报

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2015-10-13 15:54:00 | 显示全部楼层

目前已知2007、2010、2011、2014下没有问题,2008的有点特殊,6楼为2008的正确代码
回复

使用道具 举报

0

主题

275

帖子

8

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
275
发表于 2015-10-13 16:07:00 | 显示全部楼层

void 是没有返回值的,alisp 好像都需要一个返回值
回复

使用道具 举报

54

主题

552

帖子

11

银币

中流砥柱

Rank: 25

铜币
767
发表于 2015-10-13 16:28:00 | 显示全部楼层

好像是这个原因,请问如何定义一个.NET函数,参数为int a和int b,结果为a*b,这样的函数如何写?最终还是想让lisp调用的
回复

使用道具 举报

0

主题

275

帖子

8

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
275
发表于 2015-10-13 16:55:00 | 显示全部楼层
  1. [LispFunction("MyAdd")]
  2.         public static object MyAdd(ResultBuffer rbArgs)
  3.         {
  4.             var arg = rbArgs.AsArray();
  5.             if (arg.Length==2 && arg[0].TypeCode==(int)LispDataType.Double && arg[1].TypeCode==(int)LispDataType.Double)
  6.             {
  7.                 var num1 = (double)arg[0].Value;
  8.                 var num2 = (double)arg[1].Value;
  9.                 Double result = num1 + num2;
  10.                 return result;
  11.             }
  12.             else {
  13.                 return null;
  14.             }
  15.         }
C# 是区分类型的,Acad 用到的有 5001 5003 5010 ,简单的结果转为 double,否则就要 区分复制代码
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-14 13:24 , Processed in 0.443534 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表