2010-10-13 18 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