一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++ com編程學習詳解

C++ com編程學習詳解

2022-01-11 14:37不會寫代碼的絲麗 C/C++

這篇文章主要介紹了C++ COM編程的學習過程,在C++中,可以使用抽象基類來實現COM接口,需要的朋友可以參考下,希望能夠給你帶來幫助

 

COM簡介

COM全程為component object model ,是一個二進制標準可以用于跨語言調用dll模塊或者實現組件化以及復用。com不僅可以用在單個操作系統也可以用在跨服務上,在很多大型軟件如wps,office你都會看到它的身影。

比如java中調用規范如下:

JAVA COM編程

你可能會在電腦出現缺少dll情況,一種修復方式下載dll然后調用regsvr32.exe xxx.dll即可修復。

C++ com編程學習詳解

上面便是COM組件的注冊,本質是把這個dll信息注冊到注冊表中,以便其他系統軟件可以加載。

flutter也提供相關接口封裝flutter相關文檔鏈接

本文主要介紹c++下使用com規范編程

為什么需要COM?僅僅是為調用dll何必引用一個如此復雜的概念?

1.假設某個exe升級其中一個dll想要僅發布dll而不是是發布主體文件,在大多數情況下是沒有任何問題的。但是在不同編譯器編譯(或者同編譯器不同版本)出的主體exe和dll是有可能出現內存布局上的差異引起的奔潰。startoverflow上的一個經典問題

2.跨語言調用,比如c語言以結束,但是不是所有語言字符串定義都是如此。

3.跨進程或者跨服務上調度dll函數

4.dll代碼復用 與共享

 

COM 規范

com使用idl文件去定義dll函數或者接口,之后用midl編譯器生產對應的頭文件,開發者再利用其去實現接口。

接口有自己的標識符號IID 防止與其他人的接口在名字上沖突.

C++ com編程學習詳解

編譯后的某個頭文件你會看到IID_XXXXX 如下所示

C++ com編程學習詳解

如果說IID是為了標識一個接口,那么應該還有一個ID去用于標識實現類,這個實現類的id我們稱為CLSID,CLSID會在注冊表映射一個dll信息,也就是我們可以用個這個CLSID可以在注冊表中尋找到dll文件信息。

C++ com編程學習詳解

tip:一個實現類可能會包含多個接口

更多idl語法可以參閱官方指南:

https://docs.microsoft.com/en-us/windows/win32/com/defining-com-interfaces

https://bbs.csdn.net/topics/30094944?list=34484

使用ATL編寫一個com共享dll庫 使用管理員權限運行vs(編譯dll會自動調用regsvr32注冊到注冊表,但是需要權限)

 

首先創建一個ATL工程,創建后你會看到一個idl文件

C++ com編程學習詳解

新建一個接口如下:

C++ com編程學習詳解

C++ com編程學習詳解

上面ProgId一個可選項,它的作用是提供了另一種方式尋找注冊過的dll。

C++ com編程學習詳解

完成后我們的IDL會自動產生相關語法到文件中

C++ com編程學習詳解

同時會創建對應的頭文件和c文件如下

C++ com編程學習詳解

此時我們到類視圖添加一個接口方法

C++ com編程學習詳解

添加后idl同樣會如下圖所示生產對應的語法

C++ com編程學習詳解

對應的c文件自行實現接口(最后一個參數作為返回參數)

C++ com編程學習詳解

編譯后會產生 工程名_i.c和工程名.h文件,并且自動會將dll注冊注冊表中。

將上訴兩個文件拷貝其他使用工程中(注意我們并沒有拷貝dll)如下圖所示:

C++ com編程學習詳解

然后再調代碼如下所示調用:

#include <iostream>
#include"FMYALTFOUR_i.h"
int main()
{
	//初始化
	CoInitialize(NULL);
	IClassFactory *pFactory = NULL;
	//通過CLSID從注冊表中查到dll位置并加載 然后返回一個類工廠
	HRESULT hr = CoGetClassObject(CLSID_IfmyMathHelper,CLSCTX_INPROC_SERVER,
		NULL,
		IID_IClassFactory, (void**)&pFactory
		);
	//利用類工廠得到一個接口實例化對象
	IIfmyMathHelper * pSuperMath = NULL;
	pFactory->CreateInstance(NULL, IID_IIfmyMathHelper, (void**)&pSuperMath);
	long ret;
	pSuperMath->add(1, 2, &ret);
	//反初始化
	CoUninitialize();
}

當然這是其中一種調用方式,還有一種是預留給vb這類語言調用的實現這種方式你不需要拷貝上訴兩個文件,但是創建接口必須勾選接口雙重。

int main()
{
	//初始化
	CoInitialize(NULL);
	HRESULT hr;
	GUID clsid;
	IUnknown FAR* punk;
	IDispatch FAR* pdisp = (IDispatch FAR*)NULL;
	//通過progId反向查找出clsid 去加載dll
	hr = CLSIDFromProgID(OLESTR("progIdfmyMathHelper.1"), &clsid);
	IDispatch* pDispatch = NULL;
	hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pDispatch);
	LPOLESTR szMember[1] = { (LPOLESTR)OLESTR("add") };
	DISPID dipid[1] = { 0 };
	hr=pDispatch->GetIDsOfNames(IID_NULL, szMember, 1, LOCALE_USER_DEFAULT, dipid);
	CComVariant vars[2];
	DISPPARAMS args = { NULL,NULL,0,0 };
	vars[0] = 2;
	vars[1] = 1;
	args.cArgs = 2;
	args.rgvarg = vars;
	CComVariant Ret;
	hr=pDispatch->Invoke(dipid[0], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
		&args, &Ret,NULL,NULL
		);
	std::cout << "Hello World!
" << Ret.lVal;
	//反初始化
	CoUninitialize();
}

 

COM 原理學習

regsvr32.exe xxx.dll 本質作用會加載dll然后調用如下幾個函數,dll應該根據規范在對應函數中實現對應的邏輯(比如DllRegisterServer中應當實現注冊信息到注冊表中)

C++ com編程學習詳解

上面幾個函數在你創建atl工程的def文件可以看到.

我們接下來看看注冊表中的信息,dll首先會利用CLSID的數值在如下注冊表路徑創建對應的信息
計算機HKEY_CLASSES_ROOTWOW6432NodeCLSID{xxxxxxxxxxx}

C++ com編程學習詳解

C++ com編程學習詳解

如果ProgId會在如下圖位置創建額外的信息,主要用于提供其他方式尋找到dll信息。

C++ com編程學習詳解

其中32位系統和64系統可能路徑有所不同可以參考如下鏈接所示

How to use the Regsvr32 tool and troubleshoot Regsvr32 error messages

自己模擬atl的實現代碼: https://github.com/Zjvngvn/studyCom.git

ActiveX

ActiveX也是基于Com實現的一個UI組件庫。你可以在ATL下輕松的創建對應控件,然后在其他工程插入即可

C++ com編程學習詳解

 

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/qfanmingyiq/article/details/120237911

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
主站蜘蛛池模板: 丁香婷婷在线视频 | 日本一区二区精品88 | 奇米777狠狠 | 国产高清在线精品一区 | 白发在线视频播放观看免费 | 精品成人一区二区三区免费视频 | 成人国产网站v片免费观看 成人国产精品视频 | 国产欧美va欧美va香蕉在线观 | 欧美一级特黄特色大片免费 | 欧美人shou交在线播放 | 我的漂亮朋友在线观看全集免费 | 日本中文字幕黑人借宿影片 | 扒开胸流出吃奶 | 99久久国语露脸精品国产 | 欧美日韩精品在线观看 | 天堂一区二区在线观看 | 从后面撕开老师的丝袜动态图 | 亚洲国产情侣偷自在线二页 | 国产精品aⅴ | 日韩欧美一卡二区 | 国产日韩欧美综合在线 | 日韩在线观看网址 | 把内裤拔到一边高h1v1 | 日韩版码免费福利视频 | 日韩高清一区二区三区不卡 | 成全视频在线观看免费 | 性色欲情网站IWWW九文堂 | 久久精品午夜一区二区福利 | 高清不卡日本v在线二区 | 99综合视频| 午夜福利08550 | 男人午夜视频在线观看 | 黑人巨摘花第一次出血 | 男人女人插 | 欧美破处摘花 | 欧美人成绝费网站色www吃脚 | 国产午夜视频在线观看网站 | 狠狠插入 | 无码一区国产欧美在线资源 | 国产综合欧美日韩视频一区 | 性导航h|