明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 619|回复: 16

[源码] 原创!Vlisp与Cpython无缝联合开发CAD

[复制链接]
发表于 2022-5-9 13:17 | 显示全部楼层 |阅读模式
先说原理,Vlisp中可以通过(vlax-get-or-create-object obstr)这种形式调用一个已注册的Com对象,而在CPython中,利用pythoncom和win32com这两个模块则可以轻松地创建和注册一个Com server,以供lisp调用。lisp调用python建立的com接口时,可以直接把通过(vlax-get-acad-object)获取到的CAD接口通过传递参数的形式直接传给Python。Python一旦接收到了这个接口,能做的可就太多了。可以像vba一样访问CAD对象下所有的属性、事件和方法,甚至可以直接把这个接口存成一个文件,以便其他程序和进程来访问……
先说在Python中定义com server的方法。

import pythoncom  
import win32com.client as win32
import win32timezone#不导入此,无法编译为exe
from win32com.client import Dispatch
class PythonUtilities:
    _reg_clsctx_ =pythoncom.CLSCTX_LOCAL_SERVER   
    _public_methods_=['SplitString']###外部调动的方法
    _reg_progid_='PythonDemos.Utilities'
    # 先使用print (pythoncom.CreateGuid())" 得到一个自己的clsid,不要用下面这个!!
_reg_clsid_='{848B2AEB-0E17-45E1-8D8A-0A242D4607E8}'
    def SplitString(self,val):####方法定义
        retvalue=do_something()###编写业务代码
    return retvalue ####返回值
if __name__=='__main__':####自动注册server
    print ('Registering COMserver...')
    import win32com.server.register
win32com.server.register.UseCommandLine(PythonUtilities)

以上代码就定义了一个包含一个SplitString方法的com接口,运行这段代码,即可自动注册com server,如需取消注册,直接在命令行运行这个py文件,并带—unregister参数即可(无需在python源代码中写相关逻辑代码)。之后在Vlisp中运行以下代码,即可调用SplitString方法:
(defun c:tt2()
  (setq aa (vlax-get-or-create-object "PythonDemos.Utilities"))
  (setq ab (vlax-invoke aa 'SplitString ))
  )

  

在windows系统上,可以把python代码通过pyinstaller编译成exe文件,在lisp中需要调用时,先执行一遍exe,在运行上述代码即可。执行exe时可选择不显示黑框,那么在用户看来,这与直接使用纯lisp插件并无区别。

下面直接给出一个案例源代码,先运行py文件再用lisp调用即可。在实际操作中,运行py文件的代码也可一并写入lisp中。本案例中python需要先安装pysimplegui模块。


以下为运行效果 :

利用这种技术思路还以制作非模态对话框,就像Lisp自带的一样无缝嵌入:





除此之外,还可以注册cad的事件,但是经过测试,凡是涉及到数据库修改的事件,用python注册之后都会引起cad崩溃(cad2014)



但是这个方法有一个致命弱点:那就是com server在win10上极难注册成功,考虑到win10普及度如此之广,可以说是相当难办了。希望能有高手提出简单易行的解决方案。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1明经币 +1 收起 理由
菜卷鱼 + 1 厉害了

查看全部评分

发表于 2022-5-11 15:20 | 显示全部楼层
本帖最后由 flowerson 于 2022-5-11 15:44 编辑


python里的错误:
Registering COM server...
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python37\lib\site-packages\win32com\server\register.py", line 419, in RegisterClasses
    moduleName = os.path.splitext(win32api.FindFiles(sys.argv[0])[0][8])[0]
pywintypes.error: (3, 'FindFirstFile', '系统找不到指定的路径。')

cad里 错误:
Python COM Server Internal Error: Unexpected Python Error: Traceback (most recent call last):


注册出现这样的错误,有高手能帮解决吗?
 楼主| 发表于 2022-5-14 16:59 | 显示全部楼层
flowerson 发表于 2022-5-14 12:59
win10 python 3.7一直打包不成功!

我还想到一个思路:利用.NET语言,定义一个命令,这个命令的作用是,借coMarshalInterface把cad的com接口对象写成文件。然后外部程序通过counMarshalInterface再把这个文件还原成com接口对象。这样就可以实现外部程序调用指定的cad进程的com对象了。而.net只需要维护一小段代码即可。可以轻松实现跨版本。
也可以避免注册com server。
只可惜C#我水平不足,目前调用coMarshalInterface还未成功。。。
 楼主| 发表于 2022-5-11 22:56 | 显示全部楼层
flowerson 发表于 2022-5-11 18:41
楼主,请问如果是python定义的函数 ,有没有什么办法变成lisp的函数啊?
举例pthon
def pinyin(word):

对于你说的这种情况,可以通过命令行的方式传参。在py里面用getopt接收参数,通过print返回参数。在lisp里面通过exec启动py并接收返回值
发表于 2022-5-9 18:05 | 显示全部楼层
学习学习,cad下用python的资料还是不多
发表于 2022-5-10 19:39 | 显示全部楼层
同求win10注册解决办法。
 楼主| 发表于 2022-5-11 16:19 | 显示全部楼层
flowerson 发表于 2022-5-11 15:20
python里的错误:
Registering COM server...
Traceback (most recent call last):

是win10么?
发表于 2022-5-11 17:27 | 显示全部楼层
这个缺点太致命了
发表于 2022-5-11 17:28 | 显示全部楼层

是的,是win10.还有其它例子吗?
发表于 2022-5-11 18:41 | 显示全部楼层
本帖最后由 flowerson 于 2022-5-13 01:56 编辑

楼主,请问如果是python定义的函数 ,有没有什么办法变成lisp的函数啊?
举例pthon
def pi……
这样有什么好办法?


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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2022 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2022-5-18 14:50 , Processed in 0.400407 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表