Lisp与.NET互相调用。CAD2008 .net程序运行出现异常,请各位老师找出出错原因,非...
本帖最后由 革天明 于 2015-10-12 14:04 编辑李冠亿老师《深入浅出AutoCAD.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;
namespace Sample
{
class CH6_8_3
{
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;
}
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);
}
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<System::Reflection::MethodInfo ^>* 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位),
为什么这样用! ivde 发表于 2015-10-12 18:19 static/image/common/back.gif
为什么这样用!
请教如何用才对? 革天明 发表于 2015-10-13 08:56 static/image/common/back.gif
请教如何用才对?
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;
namespace Sample
{
public class MyPlugin : IExtensionApplication
{
void IExtensionApplication.Initialize()
{
}
void IExtensionApplication.Terminate()
{
}
}
public class CH6_8_3
{
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;
}
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);
}
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());
}
}
}
在XP 、CAD2007能运行。 ivde 发表于 2015-10-13 10:13 static/image/common/back.gif
class CH6_8_3 用 public class CH6_8_3
using System;
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using System.Runtime.InteropServices;
namespace Lisp2NET
{
public class MyPlugin : IExtensionApplication
{
void IExtensionApplication.Initialize()
{
}
void IExtensionApplication.Terminate()
{
}
}
class CH6_8_3
{
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;
}
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);
}
public static stringCallByLispFunction(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! yshf 发表于 2015-10-13 15:43 static/image/common/back.gif
在XP 、CAD2007能运行。
目前已知2007、2010、2011、2014下没有问题,2008的有点特殊,6楼为2008的正确代码 革天明 发表于 2015-10-13 15:54 static/image/common/back.gif
目前已知2007、2010、2011、2014下没有问题,2008的有点特殊,6楼为2008的正确代码
void 是没有返回值的,alisp 好像都需要一个返回值 ivde 发表于 2015-10-13 16:07 static/image/common/back.gif
void 是没有返回值的,alisp 好像都需要一个返回值
好像是这个原因,请问如何定义一个.NET函数,参数为int a和int b,结果为a*b,这样的函数如何写?最终还是想让lisp调用的 本帖最后由 ivde 于 2015-10-13 17:37 编辑
革天明 发表于 2015-10-13 16:28 static/image/common/back.gif
好像是这个原因,请问如何定义一个.NET函数,参数为int a和int b,结果为a*b,这样的函数如何写?最终还是 ...
public static object MyAdd(ResultBuffer rbArgs)
{
var arg = rbArgs.AsArray();
if (arg.Length==2 && arg.TypeCode==(int)LispDataType.Double && arg.TypeCode==(int)LispDataType.Double)
{
var num1 = (double)arg.Value;
var num2 = (double)arg.Value;
Double result = num1 + num2;
return result;
}
else {
return null;
}
}
C# 是区分类型的,Acad 用到的有 5001 5003 5010 ,简单的结果转为 double,否则就要 区分
if (arg.Length==2 && (arg.TypeCode==5001 ||arg.TypeCode==5003 || arg.TypeCode==5010)
&& (arg.TypeCode == 5001 || arg.TypeCode == 5003 || arg.TypeCode == 5010))
{
var num1 = arg.Value;
var num2 = arg.Value;
var result = (double)num1 + (double)num2;
return result;
}
页:
[1]
2