我有一些COM庫需要從WF4活動訪問,所以我使用tlbimp
爲它們生成託管包裝。這很好,但在一些情況下,有一個COM方法需要一個變量數組作爲其參數之一,而數組的其中一個元素是來自另一個DLL的COM類的一個實例,即使我有一個引用表示同一個對象的託管包裝的引用,也不會看到如何獲取引用。如何訪問使用TLBIMP創建的託管.NET對象的底層COM對象
舉個例子,說我有兩個叫ABC
和DEF
COM庫,爲此,我創建了託管的包裝使用tlbimp
稱爲ABCManaged
和DEFManaged
。說DEF
具有以下簽名的方法(原諒VB風格的簽名,這是它在文檔中的方式):它被作爲DEFManaged
表示如下
CallFunction (parmArray() as Variant) as Long
:
int CallFunction(ref object parmArray)
到現在爲止還挺好。現在,作爲CallFunction()
參數的變量數組的元素是不同類型的,所以在我的情況下,第一個元素是double
,第二個元素是ABC
的實例。下面是我如何建立我的數組傳遞給我的管理CallFunction()
:
// obtain our managed ABC from the workflow context
ABCManaged abc = context.GetValue(this.InputABC);
object[] parameters = new object[2];
parameters[0] = new double();
parameters[1] = abc;
DEFManaged def = new DEFManaged();
def.CallFunction(parameters);
編譯沒有問題,但不工作 - 調用CallFunction()
拋出此異常:
System.ArgumentException: Value does not fall within the expected range.
我的猜測是, def
未正確收集到底層的非託管DEF
類型,可能是因爲簽名只有一個object
的數組,並且確定數組元素的實際類型的邏輯是在COM方法的實現中的某處CallFunction()
。我無法弄清楚如何將我的def
對象手動編組到非託管DEF
類型,然後將其粘貼到陣列中以傳遞到我的託管CallFunction()
。
使用直P/Invoke在這裏也不是一個選項;我當然可以編寫代碼,但其中一個要求是WF4活動的用戶能夠訪問DEFManaged
對象上的屬性和方法,因此他們需要被管理的對象。
該對象似乎正確地編組到com服務器。否則會引發另一個異常,很可能是一個'InvalidComObjectException'或另一個'COMException'。服務器實現拋出'ArgumentException' get。 http://msdn.microsoft.com/en-us/library/9ztbc5s1.aspx – Carsten 2013-02-28 08:05:56
好吧,'object []'正在編組到'Variant()',但我的猜測是數組中的實際元素是因爲接口不知道它必須這樣做,所以沒有正確編組,因爲COM對象和它的管理對象的簽名都沒有指定數組元素的類型。 你是否認爲這個猜測是錯誤的,並且我的數組的第二個元素(在我的例子中是一個'ManagedABC'對象)被正確封送到底層COM對象(在我的例子中是一個'DEF'對象),儘管有接口沒有指定該類型? – user533676 2013-02-28 14:27:06
我誤解了這裏發生的事情:數組中的單個對象正在編組,但數組本身是通過值而不是通過引用傳遞的(COM對象要求它通過引用傳遞)。請參閱下面的答案,詳細瞭解如何解決此問題。 – user533676 2013-03-16 14:17:56