COM的INTERFACE使用实践

这篇博客介绍了如何使用C++实现COM接口来创建一个简易的数学库。首先定义了一个IMath接口,包含add和sub两个方法。接着,实现了MathImp类,继承自IMath,并覆盖了IUnknown的QueryInterface、AddRef和Release方法。最后,通过一个简单的测试程序验证了数学库的功能,展示了如何通过C语言接口调用这些方法进行加法和减法运算。
摘要由CSDN通过智能技术生成

INTERFACE用于声明库的接口,下面我们将实现一个简易的数学库来实践一下。

我们首先声明一个接口类IMath,该类继承自IUnknown;IMath有两个方法供外部调用,分别为add和sub

#undef INTERFACE
#define INTERFACE IMath
DECLARE_INTERFACE_(IMath, IUnknown) 
{
  STDMETHOD_(int, add)(THIS_ const int x, const int y) PURE;
  STDMETHOD_(int, sub)(THIS_ const int x, const int y) PURE;
};

接下来我们定义一个实现类MathImp,MathImp继承接口类IMath,由于IMath继承IUnknown,所以我们需要实现QueryInterface/AddRef/Rlease这三个函数,否则编译不过。我们在MathImp中声明这三个函数

class MathImp : public IMath
{
public:
  MathImp();
  virtual ~MathImp();

public:
  STDMETHOD(QueryInterface) (THIS_ REFIID riid, _COM_Outptr_ void** ppvObj) override;
  STDMETHOD_(ULONG, AddRef) (THIS) override;
  STDMETHOD_(ULONG, Release) (THIS) override;

public:
  STDMETHOD_(int, add)(THIS_ const int x, const int y) override;
  STDMETHOD_(int, sub)(THIS_ const int x, const int y) override;

private:
  volatile LONG m_cRef;
};

接下来我们实现MathImp,下面这三个接口是IUnknown规定要实现的

STDMETHODIMP MathImp::QueryInterface(REFIID riid, void **ppvObj)
{
  if (ppvObj == NULL)
  {
    return E_INVALIDARG;
  }
    
  *ppvObj = NULL;
  if (IsEqualIID(riid, __uuidof(IUnknown)) || IsEqualIID(riid, IID_IUnknown))
  {
    *ppvObj = (IUnknown *)this;
  }

	if (*ppvObj)
	{
		AddRef();
		return S_OK;
	}
	return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) MathImp::AddRef(void)
{
  return (ULONG)InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG) MathImp::Release(void)
{
  LONG ret = InterlockedDecrement(&m_cRef);
  if (ret == 0)
  {
    delete this;
  }
  return ret;
}

终于到了实用部分,下面这两个接口是我们真正提供给外部调用的逻辑接口

int MathImp::add(THIS_ const int x, const int y)
{
  return x + y;
}

int MathImp::sub(THIS_ const int x, const int y)
{
  return x - y;
}

ok,到这里我们的简易数学库就实现的差不多了,剩下的工作是提供C语言的创建/释放接口,不是本文的重点,请查看源代码

接下来,我们写个demo来测试这个库,看是否运行正常。

我们通过VS创建一个控制台项目,引入刚刚我们编写的库,调用C语言接口创建数学库实例,再调用数学库的Add方法对两个数字进行加法运算

#include "../interface/iMath.h"

#pragma comment(lib, "interface.lib")

using namespace System;

int main(array<System::String ^> ^args)
{
  IMathModulePtr pMathModule = CreateMathModule();
  int out = pMathModule->add(2, 8);
  Console::WriteLine(L"Add 2 and 8: ");
  Console::WriteLine(out);
  system("pause");
  
  ReleaseMathModule();
  return 0;
}

运行结果:

 ok,运行正常。

整个工程的源代码:

test/vs/interface at master · ChriFang/test · GitHubicon-default.png?t=M0H8https://github.com/ChriFang/test/tree/master/vs/interface

 参考文章:

com中的宏DECLARE_INTERFACE_『一木浮生』 的专栏-CSDN博客#undef INTERFACE#define INTERFACE ICustomResolverDECLARE_INTERFACE_(ICustomResolver, Iunknown){  //** IUnknown methods   STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObhttps://blog.csdn.net/chengshi520aaa/article/details/7492680

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值