COM 方法调用在 C#、VB.NET 中失败,但在 Python 中有效
Posted
技术标签:
【中文标题】COM 方法调用在 C#、VB.NET 中失败,但在 Python 中有效【英文标题】:COM method call fails in C#, VB.NET, but works in Python 【发布时间】:2010-10-07 18:55:11 【问题描述】:我在尝试使用的 COM 库时遇到问题。当我调用特定方法并将其传递给null
时,我得到一个 ArgumentException。这发生在我的 C# 项目和 VB.NET 项目(我使用 Nothing
调用该方法)中,我在 Visual Studio 2008 的“COM”列表中添加了库引用。当我在 Python 中调用相同的方法时,传入None
,该方法按预期工作,没有错误。我的理解是 Python 通过 DCOM 与 COM 库交互(我只有最模糊的概念),而当我在 C#/VB.NET 项目中引用它时,我可能会直接使用 COM 库。会不会发生什么事情会导致我传递的参数在它到达 COM 库之前搞砸了?我不确定这里发生了什么。我最近将 COM 库更新到了较新的版本,所以我想知道我是否在某个地方遇到了版本冲突,从而导致了异常。我从我的 C# 和 VB.NET 项目中删除了对 COM 库的所有引用,删除了所有 bin
和 obj
目录,并重新添加了引用。这确实导致显示在 obj
中的 Interop.MyCOMLibrary.dll 文件具有今天的日期,而不是我之前看到的旧日期。
我拥有的关于 COM 库的唯一文档描述该方法如下:
Public Function AddItem( _
ByVal ItemData As Variant _
) As Object
我现在正在尝试搜索有关Variant
参数的问题。
编辑:所以虽然Type.Missing
和其他解决方案可以让我顺利通过该方法调用,但尝试从该方法读取返回项目的某些字符串属性会导致:
System.Runtime.InteropServices.COMException:项目不存在。
这是另一个在 Python 中工作但在 C# 中引发异常的示例,所以我猜测更多 DCOM 与 COM 的怪异之处。或者这可能是一个线程问题,因为我正在使用 MSTest 进行测试。
【问题讨论】:
【参考方案1】:是的,null 不太可能是正确的。有几个变体表示“无数据”,例如 VT_EMPTY、VT_ERROR、VT_NULL。首先传递 Type.Missing。
【讨论】:
看起来Type.Missing
有效!我发布了一个关于如何传递 new object()
的答案,但我猜 Type.Missing
在这里更可取,因为它听起来更接近我想要传递的原始 null
。【参考方案2】:
您是否尝试过使用 Reflection.Missing 而不是 Nothing/null?
【讨论】:
我刚才试了AddItem(default(System.Reflection.Missing))
,得到了和往常一样的ArgumentException。我不确定你打算如何使用Missing
,所以我只是尝试了default()
。
@Sarah 试试System.Reflection.Missing.Value
@Sarah, @Henk:是的,就像他说的,使用 Missing.Value。
看起来可行! Hans 建议 Type.Missing
可行,我发现 new object()
可行。我认为Type.Missing
听起来更可取,因为除非必要,否则我尽量不使用Reflection
的东西。不过,我不知道这两者是否真的有任何区别。
@Sarah:System.Type.Missing 实际上在 Type 的静态构造函数中设置为等于 System.Reflection.Missing.Value。我认为 Type.Missing 是在 .NET 1.0 之后添加的,但我不确定。我知道 System.Reflection.Missing.Value 是我过去必须为所有可选参数执行此操作的方式。 Type.Missing 更短,所以我现在就使用它。【参考方案3】:
我在this article 中读到关于从 VB 到 VB.NET 的信息,它说在 .NET 中使用 object
,因为 Variant
不存在。我之前尝试过传递default(object)
,但没有成功,但我尝试将new object()
作为参数传递并且有效——没有抛出异常!我不明白为什么在应该是可选参数时必须传递对象的实例。为什么null
不能以某种方式翻译成new object()
?
在 *** 上输入这个问题是我在纠结了两天后得到这个答案的原因,因为我不得不从文档中复制/粘贴确切的方法描述。那时我注意到Variant
而不是Object
的参数。 :)
【讨论】:
【参考方案4】:您可以尝试使用System.DBNull.Value
作为参数吗?
我今天不得不以艰难的方式找到这一点。
在尝试了答案中的所有建议后,其中一些导致引发 Argument Exception,而在其他情况下,对 AddItem
的调用静默返回 null
。
我所做的是在 Visual Studio 解决方案中创建一个新的 VB 项目,其中包含一个带有单个 Shared
方法的单个类,该方法为我调用,打算将来自 VB 的 Null 作为参数传递。编译器抱怨 Null 不再使用,并建议改用System.DBNull.Value
。这成功了,正如我后来注意到的那样,System.DBNull.Value
也在 C# 项目中工作。
【讨论】:
以上是关于COM 方法调用在 C#、VB.NET 中失败,但在 Python 中有效的主要内容,如果未能解决你的问题,请参考以下文章