[英]What happens between the .NET interop layer and COM?
我在我的C#.NET項目中使用COM。
但是我調用的方法之一並沒有按預期運行。
所以我很想知道我的.NET代碼,Interop層和COM之間發生了什么。
我知道tlbimp.exe
為COM組件生成元數據包裝器,我可以在Object瀏覽器中看到這些生成的方法。
我是否能夠看到/調試在調用其中一個包裝器方法時會發生什么?
我將一個數組傳遞給下面的方法,並期望將填充此數組,但不會填充數組。 我調用以下tlbimp.exe
生成的方法,結果意外:
int GetTags(System.Array buffer)
Member of CServer.IUser
方法IDL:
[id(0x000000d5)]
HRESULT GetTags(
[in] SAFEARRAY(long) buffer,
[out, retval] long* retval);
調用此方法的.NET代碼:
Array tagsArray = Array.CreateInstance(typeof(int), tagsLength);
userWrapper.GetTags(tagsArray);
其他COM方法我稱之為正常工作。 但是,當我調用任何期望將Array作為參數的方法時,它不能按預期工作。
我假設COM互操作編組有一些有趣的東西。
所以我想知道在調用GetTags()
方法后是否可以看到發生了什么。
我也在這里閱讀了以下內容。
"if you are not satisified with the COM Interop marshaller, you can "override" just about every aspect of it through the very large and useful System::Runtime::InteropServices namespace"
我怎樣才能實現上述目標?
編輯:添加一個有效的Delphi測試腳本
procedure TComTestForm.TestUserBtnClick(Sender: TObject);
var
nCnt :integer;
User :IUser;
Persona :IUserPersona;
ArrayBounds :TSafeArrayBound;
ArrayData :Pointer;
TagList :PSafeArray;
nSize :integer;
begin
User := Session.GetUser;
ArrayBounds.lLbound := 0;
ArrayBounds.cElements := 0;
TagList := SafeArrayCreate( varInteger, 1, ArrayBounds );
User.GetTags( TagList );
if SafeArrayAccessData( TagList, ArrayData ) = S_OK then
begin
nSize := TagList.rgsabound[0].cElements;
OutLine( '----Available Tags, ' + IntToStr(nSize) + ' tags' );
for nCnt := 0 to nSize - 1 do
begin
OutLine( IntToStr( IntegerArray(ArrayData)[nCnt] ) );
end;
OutLine( '----');
SafeArrayUnAccessData( TagList );
SafeArrayDestroy( TagList );
end;
end;
另一個更新 :我只是意識到你可能意味着GetTags
本身應該填充該數組(來自COM代碼)。 但這可能永遠不會起作用,因為該參數是[in]
參數。
要使COM組件能夠填充該數組,它應該作為[in,out]參數和引用(SAFEARRAY *)傳遞。
更新 :好的,顯然我是在.NET中混合創建COM組件並從.NET調用COM組件。
CCW(com可調用包裝器)確實為COM SafeArray采用.NET數組。 我看到你在問題的代碼中創建了你的數組,但你沒有顯示你實際填充它的方式。 也許那段代碼出了問題? 你能分享一下嗎?
不確定這是否是您問題的解決方案,但我在過去遇到過COM-interop和SAFEARRAY的問題。
有一件事我從中學到的是,.NET相當於一個COM SAFEARRAY的應該永遠是object
,所以盡量通過你的數組作為object
以代替作為Array
。
我毫不猶豫地建議這個答案,但......
如果Delphi測試代碼確實有效,如其他地方所述,這意味着GetFags方法不能通過SAFEARRAY規則正常播放。 如果COM方法總是在進程中調用,那么您可以通過“手動”執行一些自定義編組來實現.NET代碼,完全遵循非托管Delphi測試代碼的功能。
作為一個粗略的輪廓,我想這將涉及:
但是,如果可以的話,更好地將COM組件更改為正確執行操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.