亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

老生常談.NET中的?COM?組件

 更新時間:2022年10月19日 10:28:34   作者:一線碼農(nóng)  
COM組件中的接口是一組由組件實現(xiàn)的,提供給客戶使用的函數(shù),這篇文章主要介紹了.NET中的?COM?組件,需要的朋友可以參考下

什么是COM組件?

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

        2.COM組件是一些小的二進(jìn)制可執(zhí)行文件,必須以二進(jìn)制的形式發(fā)布。

        3.COM組件可以給應(yīng)用程序、操作系統(tǒng)以及其它組件提供服務(wù)。

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

        5.COM組件必須是動態(tài)鏈接的。

使用COM組件需要注意:

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

2.必須要做到擴(kuò)展系統(tǒng)服務(wù)時不依賴于特定的操作系統(tǒng)。

        COM組件不是一種計算機(jī)語言;

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

        COM組件不是API函數(shù)集;

        COM組件不是類;

        COM組件中的接口是一組由組件實現(xiàn)的,提供給客戶使用的函數(shù)(在COM中的接口是一個包含函數(shù)指針數(shù)組的內(nèi)存結(jié)構(gòu),數(shù)組元素是一個由組件實現(xiàn)的函數(shù)地址)。DLL的接口就是它所輸出的函數(shù)。

一:背景

1.講故事

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

0:044> ~~[138c]s
win32u!NtUserMessageCall+0x14:
00007ffc`5c891184 c3              ret
0:061> k
 # Child-SP          RetAddr               Call Site
00 0000008c`00ffec68 00007ffc`5f21bfbe     win32u!NtUserMessageCall+0x14
01 0000008c`00ffec70 00007ffc`5f21be38     user32!SendMessageWorker+0x11e
02 0000008c`00ffed10 00007ffc`124fd4af     user32!SendMessageW+0xf8
03 0000008c`00ffed70 00007ffc`125e943b     xxx!DllUnregisterServer+0x3029f
04 0000008c`00ffeda0 00007ffc`125e9685     xxx!DllUnregisterServer+0x11c22b
05 0000008c`00ffede0 00007ffc`600b50e7     xxx!DllUnregisterServer+0x11c475
06 0000008c`00ffee20 00007ffc`60093ccd     ntdll!LdrpCallInitRoutine+0x6f
07 0000008c`00ffee90 00007ffc`60092eef     ntdll!LdrpProcessDetachNode+0xf5
08 0000008c`00ffef60 00007ffc`600ae319     ntdll!LdrpUnloadNode+0x3f
09 0000008c`00ffefb0 00007ffc`600ae293     ntdll!LdrpDecrementModuleLoadCountEx+0x71
0a 0000008c`00ffefe0 00007ffc`5cd7c00e     ntdll!LdrUnloadDll+0x93
0b 0000008c`00fff010 00007ffc`5d47cf78     KERNELBASE!FreeLibrary+0x1e
0c 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+0xa9
13 0000008c`00fff710 00007ffc`5f167e94     ntdll!TppWorkerThread+0x644
14 0000008c`00fffa00 00007ffc`600d7ad1     kernel32!BaseThreadInitThunk+0x14
15 0000008c`00fffa30 00000000`00000000     ntdll!RtlUserThreadStart+0x21

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

二:COM 多語言互操作

1. 背景

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

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

2. C# 寫一個 COM 組件

寫一個 .NET Framework 4.8 下的 32bit FlyCom 組件,一個接口,一個實現(xiàn)類,具體原理后續(xù)再分析,先搭建嘗嘗鮮, 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調(diào)用標(biāo)準(zhǔn),表示第一個接口方法是 Show,后續(xù)再聊。

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

  • 對 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 放到 注冊表,最好都生成一個強(qiáng)簽名,否則會有警告提示。

  • 注冊 com 互操作

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

3. 注冊 COM 到注冊表

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

Microsoft Windows [版本 10.0.19042.746]
(c) 2020 Microsoft Corporation. 保留所有權(quán)利。

C:\Users\Administrator>cd /d C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64

C:\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  /CodeBase
Microsoft .NET Framework 程序集注冊實用工具版本 4.8.4084.0
(適用于 Microsoft .NET Framework 版本 4.8.4084.0)
版權(quán)所有 (C) Microsoft Corporation。保留所有權(quán)利。

成功注冊了類型
成功注冊了導(dǎo)出到“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++ 調(diào)用

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

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

#include <Windows.h>
#include <string.h>
#include <iostream>

#import "FlyCom.tlb" named_guids raw_interface_only

using 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++ 調(diào)用 COM 的流程圖可以很清楚的看到,這是面向接口編程的方式,非常完美。

三:COM 多語言互通原理

1. 架構(gòu)圖

千言萬語不及一張圖。

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

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

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

相關(guān)文章

  • ASP.NET Core奇淫技巧之動態(tài)WebApi的實現(xiàn)

    ASP.NET Core奇淫技巧之動態(tài)WebApi的實現(xiàn)

    這篇文章主要介紹了ASP.NET Core奇淫技巧之動態(tài)WebApi的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 理解ASP.NET Core 啟動類(Startup)

    理解ASP.NET Core 啟動類(Startup)

    這篇文章主要介紹了ASP.NET Core 啟動類(Startup),文中運用代碼講解相關(guān)知識非常詳細(xì),感興趣的小伙伴可以參考一下
    2021-09-09
  • .net MVC使用Session驗證用戶登錄(4)

    .net MVC使用Session驗證用戶登錄(4)

    這篇文章主要為大家詳細(xì)介紹了.net MVC使用Session驗證用戶登錄的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 如何使用pm2守護(hù)你的.NET Core應(yīng)用程序詳解

    如何使用pm2守護(hù)你的.NET Core應(yīng)用程序詳解

    pm2是nodejs的一個帶有負(fù)載均衡功能的應(yīng)用進(jìn)程管理器的模塊,下面這篇文章主要給大家介紹了關(guān)于如何使用pm2守護(hù)你的.NET Core應(yīng)用程序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-10-10
  • 解決.Net Core項目發(fā)布在IIS上訪問404的問題

    解決.Net Core項目發(fā)布在IIS上訪問404的問題

    這篇文章介紹了解決.Net Core項目發(fā)布在IIS上訪問404的問題,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • ASP.NET Core使用NLog記錄日志

    ASP.NET Core使用NLog記錄日志

    這篇文章介紹了ASP.NET Core使用NLog記錄日志的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • asp.net DataSet轉(zhuǎn)換成josn并輸出示例

    asp.net DataSet轉(zhuǎn)換成josn并輸出示例

    如何將DataSet轉(zhuǎn)換成josn并輸出,這是很多新手朋友們遇到的問題,下面有個不錯的示例,希望對大家有所幫助
    2014-01-01
  • .NET Corek中Git的常用命令及實戰(zhàn)演練

    .NET Corek中Git的常用命令及實戰(zhàn)演練

    這篇文章將通過故事的形式從Git的歷史談起,并講述Git的強(qiáng)大之處。然后通過實戰(zhàn)演練教你如何在Github以及碼云上托管我們的代碼并進(jìn)行代碼的版本控制
    2019-04-04
  • asp.net 身份驗證(最簡單篇)

    asp.net 身份驗證(最簡單篇)

    在創(chuàng)建網(wǎng)站中,常常會使用到身份驗證。asp.net中內(nèi)置了幾種身份驗證的方式,如Windows、Froms、Passport等。這幾種身份驗證的方式各有不同。
    2009-05-05
  • asp.net 數(shù)據(jù)訪問層 存儲過程分頁語句

    asp.net 數(shù)據(jù)訪問層 存儲過程分頁語句

    在asp.net 網(wǎng)頁中如果在業(yè)務(wù)邏輯層分頁在使用PagedDataSource對象,但如果數(shù)據(jù)記錄過多,使用它會嚴(yán)重的損害應(yīng)用程序的性能.
    2009-12-12

最新評論