异常:带有comtypes的对象数组无效 [英] Exception: Invalid object array with comtypes

查看:915
本文介绍了异常:带有comtypes的对象数组无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在Python中通过COM在两个Autocad文档之间实现简单的复制操作。

I try to implement a simple copy operation between two Autocad documents via COM in Python.

from pyautocad import Autocad, APoint
from comtypes.client import GetBestInterface
# Get acad application
acad = Autocad(create_if_not_exists=True)
# Create a new document
doc1 = GetBestInterface(acad.Application.Documents.Add())
# add a circle in this document and make it visible
circle = GetBestInterface(doc1.ModelSpace.AddCircle(APoint(0.0, 0.0), 1.0))
doc1.Application.ZoomExtents()
# create another document
doc2 = GetBestInterface(acad.Application.Documents.Add())
# and copy the circle to the new document
doc1.CopyObjects([circle], doc2.ModelSpace)

这会抛出:

Traceback (most recent call last):
  File "copy_bug.py", line 13, in <module>
    doc1.CopyObjects([circle], doc2.ModelSpace)
  File "Anaconda2\lib\site-packages\comtypes\__init__.py", line 655, in call_with_inout
    rescode = func(self_, *args, **kw)
_ctypes.COMError: (-2145320837, None, (u'Invalid object array', u'AutoCAD.Application', u'C:\\Program Files\\Autodesk\\AutoCAD 2015\\HELP\\OLE_ERR.CHM', -2145320837, None))

同样的事情可以在VBA中通过以下方式实现:

Same thing may be accomplished in VBA with:

Dim doc1 As AcadDocument
Set doc1 = ThisDrawing.Application.Documents.add
Dim pt(0 To 2) As Double
pt(0) = 0#: pt(1) = 0#: pt(2) = 0#
Dim circ As AcadCircle
Set circ = doc1.ModelSpace.AddCircle(pt, 1)

ThisDrawing.Application.ZoomExtents

Dim doc2 As AcadDocument
Set doc2 = ThisDrawing.Application.Documents.add

Dim arry(0 To 0) As AcadEntity
Set arry(0) = circ
doc1.CopyObjects arry, doc2.ModelSpace

我试过numpy数组, c> IDispatch 接口, IAcadEntity 接口和 IAcadObject 尝试)。

I tried numpy arrays, I tried casting to the IDispatch interface, the IAcadEntity interface and IAcadObject with no success (probably a silly attempt).

circle = circle.QueryInterface(IAcadEntity)

我也试过看看 site-packages\comtypes\automation.py 。将 self.vt 设置为 VT_ARRAY |在 _set_value 中的VT_DISPATCH 没有好处,但我怀疑问题是沿着这些线,因为,如果我们更改 Dim arry 0 To 0)As AcadEntity Dim arry(0 To 0)As Variant VBA示例还会抛出数组

I also tried to look inside site-packages\comtypes\automation.py but that's above my pay grade. Setting the self.vt to VT_ARRAY | VT_DISPATCH in _set_value does no good but I suspect that the problem is along those lines because, if we change Dim arry(0 To 0) As AcadEntity to Dim arry(0 To 0) As Variant the VBA example will also throw Invalid object array.

我应该提及我取消注释 site-packages\comtypes\automation.py

I should mention that I un-commented two lines in site-packages\comtypes\automation.py:

# These are not yet implemented:
POINTER(IUnknown): VT_UNKNOWN,
POINTER(IDispatch): VT_DISPATCH,

那么......帮助?

So .... help?!

推荐答案

同时,还有一些丑陋的黑客:

Meanwhile, there are some ugly hacks like:

Dim doc1 As AcadDocument
Set doc1 = ThisDrawing.Application.Documents.add
Dim pt(0 To 2) As Double
pt(0) = 0#: pt(1) = 0#: pt(2) = 0#
Dim circ As AcadCircle
Set circ = doc1.ModelSpace.AddCircle(pt, 1)

ThisDrawing.Application.ZoomExtents
Dim EXTMIN As Variant: EXTMIN = ThisDrawing.GetVariable("EXTMIN")
Dim EXTMAX As Variant: EXTMAX = ThisDrawing.GetVariable("EXTMAX")

Call ThisDrawing.SendCommand( _
    "_SELECT Window " & CStr(EXTMIN(0)) & "," & CStr(EXTMIN(1)) & _
    " " & CStr(EXTMAX(0)) & "," & CStr(EXTMAX(1)) & vbNewLine)
doc1.SendCommand ("_COPYBASE 0,0" & vbNewLine)

Dim doc2 As AcadDocument
Set doc2 = ThisDrawing.Application.Documents.add
doc2.SendCommand ("_PASTECLIP 0,0" & vbNewLine)





$ b b


from pyautocad import Autocad, APoint
from comtypes.client import GetBestInterface

acad = Autocad(create_if_not_exists=True)
doc1 = GetBestInterface(acad.Application.Documents.Add())
circle = GetBestInterface(doc1.ModelSpace.AddCircle(APoint(0.0, 0.0), 1.0))
doc1.Application.ZoomExtents()

EXTMIN = doc1.GetVariable("EXTMIN")
EXTMAX = doc1.GetVariable("EXTMAX")

doc1.SendCommand( "_SELECT Window %f,%f %f,%f\n\r" % (
    EXTMIN[0], EXTMIN[1], EXTMAX[0], EXTMAX[1]))
doc1.SendCommand ("_COPYBASE 0,0\n\r")

doc2 = GetBestInterface(acad.Application.Documents.Add())
doc2.SendCommand ("_PASTECLIP 0,0\n\r")

(当然,您可以创建选择集,但不能选择活动;那将是疯狂)

(of course you can create a selection set but you cannot make an selection set active; that would be madness)

请发布更好的答案!

这篇关于异常:带有comtypes的对象数组无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆