简体   繁体   English

COM方法调用在C#,VB.NET中失败,但在Python中有效

[英]COM method call fails in C#, VB.NET, but works in Python

I'm having trouble with a COM library I'm trying to use. 我正在尝试使用的COM库出现问题。 I get an ArgumentException when I call a particular method and pass it null . 当我调用特定方法并将其传递为null时,我得到一个ArgumentException。 This happens to me in both a C# project and a VB.NET project (I call the method using Nothing ) where I added the library reference from the "COM" list in Visual Studio 2008. When I call this same method in Python, passing in None , the method works as expected with no errors. 在C#项目和VB.NET项目中我都会遇到这种情况(我使用Nothing调用该方法),我在Visual Studio 2008中的“COM”列表中添加了库引用。当我在Python中调用同样的方法时,传递在None ,该方法按预期工作,没有错误。 It's my understanding that Python interacts with the COM library through DCOM (and I have only the fuzziest notion what that means) whereas I might be using the COM library directly when I reference it in my C#/VB.NET projects. 我的理解是Python通过DCOM与COM库交互(我只有最模糊的概念是什么意思)而我可能在我的C#/ VB.NET项目中引用它时直接使用COM库。 Could something be happening that would cause the parameter I pass to get screwed up before it gets to the COM library? 可能发生的事情会导致我传递的参数在进入COM库之前被搞砸了吗? I'm not sure what's happening here. 我不确定这里发生了什么。 I recently updated the COM library to a newer version, so I wondered if perhaps I was getting version conflicts in there somewhere, causing the exception. 我最近将COM库更新为更新的版本,所以我想知道是否可能在那里遇到版本冲突,导致异常。 I removed all references to the COM library from my C# and VB.NET projects, deleted all bin and obj directories, and re-added the reference. 我从C#和VB.NET项目中删除了对所有COM库的引用,删除了所有binobj目录,并重新添加了引用。 This did cause the Interop.MyCOMLibrary.dll file that shows up in obj to have today's date instead of the older date I had been seeing. 这确实导致在obj中显示的Interop.MyCOMLibrary.dll文件具有今天的日期而不是我以前看到的旧日期。

The only documentation I have for the COM library describes the method as follows: 我对COM库的唯一文档描述了如下方法:

Public Function AddItem( _
   ByVal ItemData As Variant _
) As Object

I'm trying to search around for issues regarding Variant parameters now. 我正在尝试现在搜索有关Variant参数的问题。

Edit: so while Type.Missing and the other solutions work for getting me past that method call without error, trying to read certain string properties on the returned item from that method result in: 编辑:所以当Type.Missing和其他解决方案工作让我通过该方法调用没有错误时,尝试从该方法读取返回项目的某些字符串属性导致:

System.Runtime.InteropServices.COMException: Item does not exist. System.Runtime.InteropServices.COMException:项不存在。

This is another example where it worked in Python but is throwing an exception in C#, so I'm guessing more DCOM-versus-COM weirdness. 这是另一个在Python中工作但在C#中抛出异常的例子,所以我猜测更多的DCOM与COM的怪异。 Or perhaps this is a threading issue, since I'm using MSTest to test. 或者这可能是一个线程问题,因为我正在使用MSTest进行测试。

Yes, null is not likely to be correct. 是的,null不太可能是正确的。 There are a couple of Variants that indicate "no data", like VT_EMPTY, VT_ERROR, VT_NULL. 有几个变量表示“无数据”,如VT_EMPTY,VT_ERROR,VT_NULL。 Start by passing Type.Missing. 首先传递Type.Missing。

您是否尝试使用Reflection.Missing而不是Nothing / null?

I read in this article about going from VB to VB.NET and it said to use object in .NET since Variant doesn't exist. 我在这篇文章中读到了从VB到VB.NET的问题,它说在.NET中使用object ,因为Variant不存在。 I had previously tried passing default(object) , which didn't work, but I tried passing new object() as the parameter and that worked--no exception was thrown! 我之前尝试过传递default(object) ,这不起作用,但我尝试传递new object()作为参数,并且工作 - 没有抛出异常! What I don't understand is why an instance of an object has to be passed when that's supposed to be an optional parameter. 我不明白的是为什么当一个对象的实例应该是一个可选参数时必须传递它。 Why does null not get translated somehow to new object() ? 为什么null不能以某种方式转换为new object()

Typing up this question on StackOverflow is what led me to this answer after two days of puzzling over it, because I had to copy/paste the exact method description from documentation. 在StackOverflow上输入这个问题后,经过两天的困惑,我得到了这个答案,因为我必须从文档中复制/粘贴确切的方法描述。 That's when I noticed Variant instead of Object for the parameter. 那是我注意到Variant而不是Object的参数。 :) :)

Could you try using System.DBNull.Value as an argument? 你能尝试使用System.DBNull.Value作为参数吗?

I had to find this the hard way today. 我今天必须找到这个艰难的方式。 After trying all the suggestions in the answers, some of them caused an Argument Exception to be thrown, and in other cases, the call to AddItem silently returned null . 在尝试了答案中的所有建议之后,其中一些会导致抛出Argument Exception,而在其他情况下,对AddItem的调用会以静默方式返回null

What I did was create a new VB project in the Visual Studio Solution, with a single class with a single Shared method that did the call for me, intending to pass Null from VB as an argument. 我所做的是在Visual Studio解决方案中创建一个新的VB项目,其中一个类具有单个Shared方法,该方法为我调用,打算从VB传递Null作为参数。 The compiler complained that Null is no longer used, and suggested to use System.DBNull.Value instead. 编译器抱怨不再使用Null,并建议使用System.DBNull.Value This did the trick, and as I later noticed, System.DBNull.Value worked in the C# project as well. 这样做了,我后来注意到, System.DBNull.Value也在C#项目中工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM