日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

老生常談.NET中的 COM 組件

瀏覽:435日期:2022-06-08 15:36:12
目錄
  • 什么是COM組件?
  • 使用COM組件需要注意:
  • 一:背景
    • 1.講故事
  • 二:COM 多語言互操作
    • 1. 背景
    • 2. C# 寫一個 COM 組件
    • 3. 注冊 COM 到注冊表
    • 4. 使用 C++ 調用
  • 三:COM 多語言互通原理
    • 1. 架構圖

什么是COM組件?

1.COM組件是以WIN32動態鏈接庫(DLL)或可執行文件(EXE)形式發布的可執行代碼組成。

2.COM組件是一些小的二進制可執行文件,必須以二進制的形式發布。

3.COM組件可以給應用程序、操作系統以及其它組件提供服務。

4.自定義的COM組件可以在運行時刻同其它組件連接起來構成某個應用程序。

5.COM組件必須是動態鏈接的。

使用COM組件需要注意:

1.必須要保證升級應用時不破壞與以前版本的向后兼容性;

2.必須要做到擴展系統服務時不依賴于特定的操作系統。

COM組件不是一種計算機語言;

COM組件不是DLL,只是利用DLL來給組件提供動態鏈接的能力;

COM組件不是API函數集;

COM組件不是類;

COM組件中的接口是一組由組件實現的,提供給客戶使用的函數(在COM中的接口是一個包含函數指針數組的內存結構,數組元素是一個由組件實現的函數地址)。DLL的接口就是它所輸出的函數。

一:背景

1.講故事

最近遇到了好幾起和 COM 相關的Dump,由于對 COM 整體運作不是很了解,所以分析此類dump還是比較頭疼的,比如下面這個經典的 COM 調用棧。

0:044> ~~[138c]swin32u!NtUserMessageCall+0x14:00007ffc`5c891184 c3      ret0:061> k # Child-SP  RetAddr       Call Site00 0000008c`00ffec68 00007ffc`5f21bfbe     win32u!NtUserMessageCall+0x1401 0000008c`00ffec70 00007ffc`5f21be38     user32!SendMessageWorker+0x11e02 0000008c`00ffed10 00007ffc`124fd4af     user32!SendMessageW+0xf803 0000008c`00ffed70 00007ffc`125e943b     xxx!DllUnregisterServer+0x3029f04 0000008c`00ffeda0 00007ffc`125e9685     xxx!DllUnregisterServer+0x11c22b05 0000008c`00ffede0 00007ffc`600b50e7     xxx!DllUnregisterServer+0x11c47506 0000008c`00ffee20 00007ffc`60093ccd     ntdll!LdrpCallInitRoutine+0x6f07 0000008c`00ffee90 00007ffc`60092eef     ntdll!LdrpProcessDetachNode+0xf508 0000008c`00ffef60 00007ffc`600ae319     ntdll!LdrpUnloadNode+0x3f09 0000008c`00ffefb0 00007ffc`600ae293     ntdll!LdrpDecrementModuleLoadCountEx+0x710a 0000008c`00ffefe0 00007ffc`5cd7c00e     ntdll!LdrUnloadDll+0x930b 0000008c`00fff010 00007ffc`5d47cf78     KERNELBASE!FreeLibrary+0x1e0c 0000008c`00fff040 00007ffc`5d447aa3     combase!CClassCache::CDllPathEntry::CFinishObject::Finish+0x28 [onecore\com\combase\objact\dllcache.cxx @ 3420] 0d 0000008c`00fff070 00007ffc`5d4471a9     combase!CClassCache::CFinishComposite::Finish+0x4b [onecore\com\combase\objact\dllcache.cxx @ 3530] 0e 0000008c`00fff0a0 00007ffc`5d3f1499     combase!CClassCache::FreeUnused+0xdd [onecore\com\combase\objact\dllcache.cxx @ 6547] 0f 0000008c`00fff650 00007ffc`5d3f13c7     combase!CoFreeUnusedLibrariesEx+0x89 [onecore\com\combase\objact\dllapi.cxx @ 117] 10 (Inline Function) --------`--------     combase!CoFreeUnusedLibraries+0xa [onecore\com\combase\objact\dllapi.cxx @ 74] 11 0000008c`00fff690 00007ffc`6008a019     combase!CDllHost::MTADllUnloadCallback+0x17 [onecore\com\combase\objact\dllhost.cxx @ 929] 12 0000008c`00fff6c0 00007ffc`6008bec4     ntdll!TppTimerpExecuteCallback+0xa913 0000008c`00fff710 00007ffc`5f167e94     ntdll!TppWorkerThread+0x64414 0000008c`00fffa00 00007ffc`600d7ad1     kernel32!BaseThreadInitThunk+0x1415 0000008c`00fffa30 00000000`00000000     ntdll!RtlUserThreadStart+0x21

為了做一個簡單的梳理,我們搭建一個簡單的多語言 COM 互操作。

二:COM 多語言互操作

1. 背景

可能很多新生代的程序員都不知道 COM ,最多也只聽過這個名詞,其實在 Windows 上有海量的 COM 組件,這些組件信息都是注冊在 HKEY_CLASSES_ROOT\CLSID 節點目錄,截圖如下:

這個和微服務中的 注冊中心 是一個道理,這一篇我們用 C# 寫一個COM組件,用 C++ 去調用。

2. C# 寫一個 COM 組件

寫一個 .NET Framework 4.8 下的 32bit FlyCom 組件,一個接口,一個實現類,具體原理后續再分析,先搭建嘗嘗鮮, C# 代碼如下:

namespace FlyCom{    [Guid("31A3CED7-B4F1-4D59-881A-EA1D7ABCC4CF")]    public interface BaseFly    {[DispId(1)]string Show(string str);    }    [Guid("270C3ED3-053D-4324-9176-9C3FA2BE58A7")]    [ProgId("FlyCom.Show")]    public class Fly : BaseFly    {public string Show(string str){    return $"str={str}, length={str.Length}";}    }}

這里簡單說一下:

1.Guid

一個是接口(BaseFly) 的唯一碼,即 IID 信息, 一個是 COM組件的 唯一碼,叫做 CLSID。

2.ProgId

因為 GUID 不方便記憶,所以給這個 COM組件 取一個別名叫 FlyCom.Show

3.DispId

這個是為了遵循 COM多語言互通下的 vtable調用標準,表示第一個接口方法是 Show,后續再聊。

有了代碼,接下來還要做三個配置。

  • 對 COM 的可見性

修改 AssemblyInfo.cs 中的 ComVisible = true,參考如下:

// Setting ComVisible to false makes the types in this assembly not visible// to COM components.  If you need to access a type in this assembly from// COM, set the ComVisible attribute to true on that type.[assembly: ComVisible(true)]
  • 生成簽名

一般來說,將 com 放到 注冊表,最好都生成一個強簽名,否則會有警告提示。

  • 注冊 com 互操作

在屬性面板中,選擇 Build 選項卡,選中 Register for COM interop 選項即可。

3. 注冊 COM 到注冊表

要將 com組件 放到注冊表,需要使用注冊表編輯工具 regasm

Microsoft Windows [版本 10.0.19042.746](c) 2020 Microsoft Corporation. 保留所有權利。C:\Users\Administrator>cd /d C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64>C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe D:\net6\ConsoleApp1\FlyCom\bin\Debug\FlyCom.dll /tlb:FlyCom.tlb  /CodeBaseMicrosoft .NET Framework 程序集注冊實用工具版本 4.8.4084.0(適用于 Microsoft .NET Framework 版本 4.8.4084.0)版權所有 (C) Microsoft Corporation。保留所有權利。成功注冊了類型成功注冊了導出到“D:\net6\ConsoleApp1\FlyCom\bin\Debug\FlyCom.tlb”的程序集和類型庫C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64>

從輸出中可以看到已成功注冊,并且生成了一個 FlyCom.tlb 代理文件,接下來可以到注冊表中驗證一下 GUID=270C3ED3-053D-4324-9176-9C3FA2BE58A7 注冊項以及別名為 FlyCom.Show 的注冊項。

4. 使用 C++ 調用

要想 C++ 調用 C# 寫的 COM 組件,就像 RPC 調用一樣,直接自動生成的代理文件即可,將 FlyCom.tlb 復制到 根目錄,并且將程序改成 Win32 位,截圖如下:

接下來就是完整的 C++ 代碼。

#include <Windows.h>#include <string.h>#include <iostream>#import "FlyCom.tlb" named_guids raw_interface_onlyusing namespace std;int main(){	CoInitialize(NULL);	FlyCom::BaseFlyPtr ptr;	ptr.CreateInstance("FlyCom.Show");	wchar_t* c = ptr->Show(L"hello world");	wprintf(L"%s", c);	getchar();}

將程序跑起來后,真的很完美。

從 C++ 調用 COM 的流程圖可以很清楚的看到,這是面向接口編程的方式,非常完美。

三:COM 多語言互通原理

1. 架構圖

千言萬語不及一張圖。

這就是 COM 能夠實現多語言互通的規范,熟悉 C++ 的朋友肯定知道 vtable ,C++ 能夠實現多態,全靠這玩意,COM 也是用了 vtable 這套模式,所以諸如 JAVA,C#,VBS 必須在二進制層面將代碼組織成上圖這種形式,才能實現 COM 的互通。

所以在 C# 中你看到的 DispId 特性就是為了按照 vtable 方式進行組織,對于 ole32 和 combase 這些 COM 運行環境的基石,我們后續用 windbg 來解讀一下,這一篇就先到這里,希望對你有幫助。

到此這篇關于 老生常談.NET中的 COM 組件的文章就介紹到這了,更多相關.NET COM 組件內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: ASP.NET
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品白丝一区二区三区| 日本国产一区| 日韩在线短视频| 亚洲国产成人二区| 久久久久久久久99精品大| 国产农村妇女精品一区二区| 偷拍亚洲精品| 高清av一区| 最新日韩欧美| 国产精品xxx| 日本黄色精品| 免费日韩精品中文字幕视频在线| 欧美自拍一区| 久久人人97超碰国产公开结果| 在线日韩成人| av日韩中文| 亚洲精品自拍| 亚洲精品福利电影| 免费成人在线视频观看| 国产欧美日韩免费观看| 久久三级视频| 久久国产精品色av免费看| 天堂中文在线播放| 日韩一区二区三区在线看| 国产成人在线中文字幕| 亚洲综合国产| 国产成人a视频高清在线观看| 亚洲深夜av| 国产精品22p| 午夜日韩福利| 麻豆91精品视频| 综合精品一区| 999久久久精品国产| 欧美精品影院| 在线综合亚洲| 日本免费一区二区三区四区| 午夜精品福利影院| 久久久国产精品一区二区中文| 日本va欧美va精品| 欧美精品一线| 国产一区二区三区四区五区| 亚洲精品乱码| 国产一区二区中文| 精品一区二区三区中文字幕视频| 日韩精品一二区| 日本在线精品| 欧美激情福利| 中文字幕日韩高清在线| 日本а中文在线天堂| 国产视频一区二| 男女男精品网站| 亚洲1234区| 国产精品v亚洲精品v日韩精品| 亚洲欧美网站| 欧美亚洲精品在线| 里番精品3d一二三区| 日本欧洲一区二区| 99久久久久国产精品| 国产精品久久久久av蜜臀| 丝袜a∨在线一区二区三区不卡| 精品亚洲美女网站| 超碰在线99| 国产激情久久| 欧美在线不卡| 日韩精品五月天| 中文一区一区三区免费在线观 | 亚洲精品成人一区| 久久久精品网| 老色鬼精品视频在线观看播放| 快she精品国产999| 亚洲高清不卡| 夜鲁夜鲁夜鲁视频在线播放| 欧美aa在线视频| 亚洲aa在线| 免费精品视频| 99亚洲精品| 欧美大黑bbbbbbbbb在线| 日韩中文在线电影| 水蜜桃久久夜色精品一区| 免费亚洲一区| 麻豆视频一区二区| 国产精品巨作av| 91亚洲无吗| 日本视频在线一区| 日本色综合中文字幕| 日韩国产一二三区| 奇米亚洲欧美| 91精品国产自产精品男人的天堂| 一区二区三区网站| 蜜臀a∨国产成人精品| 久久亚洲美女| 蜜臀91精品一区二区三区| 视频一区二区三区中文字幕| 中文在线一区| 视频在线在亚洲| 日韩影院在线观看| 老司机精品久久| 红桃视频国产一区| 久久一二三区| 亚洲伊人精品酒店| 亚洲综合色婷婷在线观看| 综合日韩在线| 日韩国产91| 美女视频一区在线观看| 久久亚洲精精品中文字幕| 精品国产乱码久久久久久樱花| 久久99国产精品视频| 鲁鲁在线中文| 欧美va天堂| 快she精品国产999| 91嫩草精品| 久久亚洲黄色| 亚洲一级少妇| 欧美 日韩 国产精品免费观看| 91九色精品| 老牛国产精品一区的观看方式| 亚洲+小说+欧美+激情+另类| 欧美日韩夜夜| 成人在线黄色| 蜜桃国内精品久久久久软件9| 日韩专区欧美专区| 911亚洲精品| 久久精品国产99| 日韩在线欧美| 夜夜嗨一区二区| 日本久久二区| 麻豆精品新av中文字幕| 成人片免费看| 婷婷综合亚洲| 亚洲精品九九| 精品视频在线观看网站| 欧美亚洲tv| 日韩高清成人| 亚洲欧美不卡| 国产精品亚洲欧美| 成人精品天堂一区二区三区| 快she精品国产999| 国产精品扒开腿做爽爽爽软件| 亚洲精品.com| 亚洲久草在线| 极品av在线| 日本欧洲一区二区| 国产精品网站在线看| 久久国产欧美| 91综合久久爱com| 国产在线|日韩| 亚洲精品伊人| 精品久久视频| 性一交一乱一区二区洋洋av| 欧美激情福利| 丝袜诱惑制服诱惑色一区在线观看| 久久av中文| 国产精品三上| 国内在线观看一区二区三区 | 伊人成人在线视频| 国产日韩1区| 欧美日韩免费看片| 婷婷亚洲精品| 99久久久久| 国产精品久久久亚洲一区| 亚洲福利免费| 国产精品丝袜在线播放| 美女久久久久| 国产精品亚洲二区| 不卡在线一区二区| 久久99视频| 免费看日韩精品| sm久久捆绑调教精品一区| 亚洲无线观看| 亚洲www啪成人一区二区| 欧美日韩黄网站| 亚洲国产影院| 精品一区二区三区在线观看视频| 久久亚洲风情| 日韩三区免费| 欧美国产免费| 亚洲综合小说| 国产综合欧美| 国产一区二区三区天码| 日韩国产91| 欧美综合国产| 999国产精品视频| 精品一区二区三区的国产在线观看| 首页国产欧美日韩丝袜| 精品欧美一区二区三区在线观看| 国产精品一区二区三区av麻| 免费久久99精品国产自在现线| 久草免费在线视频| 欧美黄色一区| 97久久超碰| 免费看欧美美女黄的网站| 亚洲成人精品| 精品免费视频| 国产精品手机在线播放| 亚洲乱码久久| 亚洲激情另类| 99久久九九| 久久久久久一区二区| 国产精品国产三级在线观看| 日韩制服丝袜av|