为什么我可以从 IronPython 访问这个 API 而不是 Python.NET?

问题描述

我正在处理一个使用 Tekla EPM Open API 的项目。

我使用 IronPython 与它交互没有任何困难,但使用 Python.NET 的运气较差,我更喜欢它与其他模块的更大兼容性。

API 文档说明:

dll文件中只有一个函数可以调用。 c 风格的声明是:

char *_FabSuiteXML( char * );

相应地,以下(混淆的)代码在 IronPython 中按预期工作(3.4.0a1,.NETFramework v4.6 on .NET Framework 4.8.4360.0 (64-bit) o​​n win32):

import clr
import sys
sys.path.append('[…]\\Tekla\\Tekla EPM')
clr.AddReference("FabSuiteAPI")
import FabSuite

interface = FabSuite.FabSuiteAPI.FabSuiteAPI()

connection_string = '''
<FabSuiteXMLRequest>
<Connect>
<IPAddress>XXX.XXX.X.XX</IPAddress>
<PortNumber>XXX</PortNumber>
<Username>XXXXXX</Username>
</Connect>
</FabSuiteXMLRequest>'''

connection_response = interface.FabSuiteXML(connection_string)

print(interface)
#Yields: <FabSuite.FabSuiteAPI.FabSuiteAPI object at 0x000000000000002B [FabSuite.FabSuiteAPI.FabSuiteAPI]>

print(connection_response)
#Yields:
"""
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<FabSuiteXMLResponse xmlns="http://www.fabsuite.com/xml/fabsuite-xml-response-v0108.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Lang>en</Lang>
  <Connect>
    <Successful>1</Successful>
    <FabSuiteMajorVersion>XXXX</FabSuiteMajorVersion>
    <FabSuiteMinorVersion>XXXX</FabSuiteMinorVersion>
  </Connect>
"""

但是,在使用 Python.NET 的(普通)python (3.9.5) 中,我收到错误

Traceback (most recent call last):
  File "[…]\overflow_question_code1.py",line 15,in <module>
    connection_response = interface.FabSuiteXML(connection_string)
AttributeError: 'FabSuiteAPI' object has no attribute 'FabSuiteXML'

实际上,python 的 help() 仅显示了从 System.Object 继承的 FabSuiteAPI 对象的那些方法

知道为什么关键方法在 Python.NET 中不可用吗?

相关的无用问题: Python: AttributeError: 'module' object has no attribute 'AddReference'?

解决方法

Python.NET 2.5 不支持 COM 互操作。这是tracking issue

有一个长词 workaround using .NET reflection

顺便说一句,如果 COM 互操作是使用 Python.NET 的原因,您实际上可能会更好地使用本机 Python COM 客户端库,例如 win32com