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,运行正常。
整个工程的源代码:
参考文章: