obj As Object = CreateObject(“THIRDPARTY.ThirdPartyObject”)
然后我们在这个COM对象上调用一个方法(VB文件头部的Option Strict Off):
obj.AMethod(ByVal Arg1 As Integer,ByVal Arg2 As Integer,ByVal Arg3 as Boolean)
我有点不知道即使这个调用有效,如果我改为使用Add Reference添加对COM服务器的引用,则在创建的COM interop .dll中不存在此重载.它所说的唯一可用的调用方法是AMethod().
然而,这本身并不困扰我.困扰我的是这个调用有效一段时间,然后在几十个调用成功执行后抛出一个TargetParameterCountException.
我问你,StackOverflow:
什么.的.地狱.
我唯一可以猜到的是COM组件的文档声明这个方法是同步执行的 – 所以也许是什么负责抛出异常被阻止直到一些不确定的时间点?除此之外,我完全被这种奇怪的,更重要的是不一致的行为所困扰.
编辑#1:
我记得的更重要的信息 – 有时调用会抛出ExecutionEngineException.它只是瞥了一眼文档才意识到这是非常糟糕的.做一点挖掘告诉我,后期绑定调用导致堆栈损坏,导致整个CLR崩溃.据推测,这意味着运行时会在某些时候击落坏调用(使用TargetParameterCountException)并丢失它们(ExecutionEngineException)其他.
编辑#2:
回答David Lively的问题:
>目前在代码中的零参数调用已存在很长时间了.在过去的两次重大修改之前,我无法获得第三方COM实施的手册,因此他们可能会从服务中撤回该签名
>调用此方法只有一个位置
>这是一台桌面应用,在同一台机器上呼叫另一台应用.没有什么花哨
>该对象在用户与应用程序的交互范围内持久存在,因此永远不会创建新对象.
不幸的是,正如您所建议的那样,实施中确实存在错误.这个供应商的问题是,当我们报告错误时,他们的反应往往遵循一般形式:i)否认存在问题; ii)否认这是他们的问题; iii)拒绝修理它.这三个步骤往往跨越令人沮丧的长时间.
不,它不会导致堆栈损坏. IDispatch :: Invoke()用于调用方法,参数打包在一个数组中. IDispatch的库存实现肯定会检测到参数不匹配,它使用类型库信息来检查.但可以想象COM服务器作者自己实现了它.不完全.这是C黑客可能会做的事情,股票实施非常缓慢. GC堆被破坏是在执行不完整代码时发生的事情.