2010-10-13 54 views
4

我正在调用合作伙伴应用程序的COM组件的应用程序。我们是.Net,他们不是。我对COM不太了解;我知道,我们调用的组件是后期绑定即从.net调用的奇怪COM行为.net

obj As Object = CreateObject("THIRDPARTY.ThirdPartyObject")

然后我们把这个COM对象的方法(strict选项关闭在VB文件头):

obj.AMethod(ByVal Arg1 As Integer, ByVal Arg2 As Integer, ByVal Arg3 as Boolean)

即使这个调用起作用,这个重载也不存在于COM互操作.dll中,如果我使用Add Reference添加对COM服务器的引用,则创建这个重载。该方法可用的唯一调用方法是AMethod()

但是,这本身并不是什么困扰我。令我困扰的是,这个调用工作一段时间,然后在几十次调用成功执行后抛出TargetParameterCountException

我问你这样,StackOverflow:

什么。的。地狱。

我唯一能猜到的是COM组件的文档声明这个方法是同步执行的 - 所以也许任何负责抛出异常的东西都被阻塞,直到某个不确定的时间点被阻止为止。除此之外,我完全迷恋在这个离奇的,更重要的是行为不一致

编辑#1:

更多的是我刚刚想起显著信息 - 不时的调用抛出ExecutionEngineException代替。它只是看了一眼文件,意识到这是非常糟糕。做一点挖掘,暗示了后期绑定调用导致堆栈损坏,导致整个CLR崩溃。这可能意味着运行时间在某些时候击落了坏的电话(与TargetParameterCountException)并且错过了其他电话(ExecutionEngineException)。

编辑#2:

接听大卫·莱弗利的问题:

  • 调用零参数这是目前在代码已经存在了很长一段时间。我之前没有能够获得第三方COM实现的手册,因此可能他们已经从服务中撤回了该签名
  • 该方法只有一个位置被调用
  • 这是一个桌面应用程序调用另一台,在同一台机器上。没有什么奇特的东西
  • 该对象在用户与应用程序交互的整个范围内都存在,因此从未创建过一个新对象。

不幸的是,正如您所建议的,很可能在实现中确实存在一个错误。这个供应商的麻烦是,当我们报告一个bug时,他们的回应往往遵循一般形式:i)否认有问题; ii)否认这是他们的问题; iii)拒绝修复它。这三个步骤往往跨越一段令人沮丧的长时间。

回答

0

行,基本上 - 虚惊一场。我做错了 - 我从某处不正确地复制了一些代码,并且我打电话的内容是永远不应该是来支持超载。我觉得有趣的是,这个组件并没有拒绝那个迟到的呼叫,但是做了它应该做的所有事情,至少在最初阶段。

1

我还没有和调用相当长的一段从VB COM对象出场,但我还是要胡乱猜测:

我期望一个例外,如果你正在调用太物体被抛出很少或太多的论点,但它似乎并非如此。你打电话的方法的真正特征是什么?

在某些语言和某些情况下,当您调用一个方法时,参数将放置在堆栈上。如果放置的参数太多,则可能会在方法完成后将多余的参数保留在堆栈中。但是,这应该会导致很多其他问题。

一些可能性/注意事项:

  1. 对象在内部抛出此异常。这应该由作者来处理。

  2. 您的呼叫参数太多。如果如您所说,您试图调用的重载不会在对象的类型库中发布,那么您可能实际上正在调用具有不同签名的其他已发布方法。如果是这样的话,我真的会期待一个编译器错误。

  3. 您以后的调用发生在您的代码的相同部分,还是有一个不同的执行分支,可能会做一些不同的事情,并导致错误?

  4. 你是从桌面应用程序/脚本或网站运行这个吗?如果网站,您是否收到有效的预期响应,或者请求挂起,如果内部长时间运行的流程没有完成?

  5. 该对象可能正在分配而不释放资源,这些资源耗尽时可能导致未定义的行为。

  6. 你是否在调用之间释放对象,还是每次都重新创建对象?

此外,回复:你对评论后期绑定:实例化一个COM对象的.CreateObject()方法是正常的,接受的方式来做到这一点。这与这个问题应该没有任何关系。根据您列出的例外情况,我强烈倾向于认为该对象存在内部问题。

祝你好运。

3

不,它不会导致堆栈损坏。 IDispatch :: Invoke()用于调用方法,参数打包在一个数组中。 IDispatch的库存实现当然会检测到参数不匹配,它使用类型库信息来检查。但可以想象,COM服务器作者自己实现了它。不完全。这是C++黑客可能做的事情,股票的实施速度非常慢。被损坏的GC堆是在不完善的代码执行时发生的事情。

+1

+1我们在我们的传统C++代码中有我们自己的IDispatch实现。为每个IDispatch调用手动实施参数检查。 – 2010-10-13 17:32:46

+0

这是值得了解的 - 我可以问他们是否有自定义IDispatch接口。这是一个开始。 – 2010-10-13 17:43:05