一场因为想偷懒引发的那些事——COM的那些事2

本文介绍了在C#中如何封装和创建COM接口对象,通过实例展示了使用公开方法和通用创建方法创建COM对象的过程,包括C++的调用方式和C#的封装示例。
摘要由CSDN通过智能技术生成

参考&&引用

What Is a COM Interface?

Creating an Object in COM

起因

看来人总是健忘的,只能隐约的记得是因为一个关于C#封装的COM接口的问题。于是自己动手封装实现了一下,接着就引发了下面一系列的问题。
一场因为想偷懒引发的那些事——COM的那些事1
一场因为想偷懒引发的那些事——COM的那些事2
一场因为想偷懒引发的那些事——WinDbg的简单用法
一场因为想偷懒引发的那些事——记C# Com接口调用的相关姿势
一场因为想偷懒引发的那些事——C#调用COM的一个进阶使用方式
一场因为想偷懒引发的那些事番外——结构体的一些事

这是一个开头

上一篇大概写了一下COM 接口的结构、布局,这次就简短的说一下怎么创建一个COM的对象。

创建一个COM 对象主要有两种方式:

  1. 使用公开的方法。
  2. 使用 CoCreateInstance 这个通用创建方法。

因为我喜欢吃柚子 ,所以就拿水果来举个例子,例如叫IFruit。下面就可以开始创建水果这个对象的过程了。

使用方法一

一般来说使用这种方式都会有一个方法 例如本次的叫做

HRESULT CreateFruit(IFruit** iFruit)

在C++中调用方式就可以是这样

IFruit* fruit=nullptr;

auto result=CreateFruit(&fruit);
if(SUCCEEDED(hr))
{
    std::cout<<"get a fruit"<<std::endl;
}
else
{
    std::cout<<" fail "<<std::endl;
}

结合上一篇可以得知, CreateFruit这个方法 开辟了一块内存空间,这里方式IFruit的一个函数表,传入 IFruit* 的地址,则是CreateFruitIFruit* 指向了该地址。

Windows 中有不少这样的函数,例如:

SHSTDAPI SHCreateItemFromParsingName(_In_ PCWSTR pszPath, _In_opt_ IBindCtx *pbc, _In_ REFIID riid, _Outptr_ void **ppv);
//这里SHSTDAPI为宏, 定义为 #define SHSTDAPI          EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
//展开即为 extern "C" __declspec(dllimport) HRESULT __stdcall

C# 中想要调用这个方法就需要对其进行封装, 简单的封装可以为这样

[DllImport("Shell32.dll")]
public extern static int SHCreateItemFromParsingName([In][MarshalAs(UnmanagedType.LPWStr)] string pszPath, [In] IntPtr pbc,
                                                     [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppv);

然后对其调用,即可以根据传入的riid得到不同的COM接口对象。

使用方法二

在使用CoCreateInstance这个方法之前,先看看其定义:

HRESULT CoCreateInstance(
  REFCLSID  rclsid,  //要创建对象的guid
  LPUNKNOWN pUnkOuter, //表示这个对象是不是属于aggregate,Null代表不是 ps:aggregate这里指COM重用方式的一种,其他的还有Containment
  DWORD     dwClsContext, // 指定对象运行的上下文,例如:CLSCTX_INPROC_SERVER 同一进程.CLSCTX_LOCAL_SERVER不同进程但是同一台电脑
  REFIID    riid,  // 这个对象实现的接口
  LPVOID    *ppv  //接收指向这个接口的指针,因为改方法是通用方法所以此类型不能为强类型,只能是void**
);

例如,如果要创建一个名为柚子的对象,使用即为:

IFruit* fruit=nullptr;
CoCreateInstance(CLSID_Pomelo,NULL,CLSCTX_INPROC_SERVER,IID_IFruit,(void**)&fruit)

至此,就可以拿着这个IFruit 进行榨汁做罐头 等水果相应的操作了。

结束

这篇只是大致介绍了一下COM对象的创建方式,很多相关的细节没有写,以后有空(等我学习完)再来补充细节吧😅

接下来就是此偷懒系列的终篇了,终于要结尾了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值