实现 COM 接口 C++ / VC++ 6.0 / MFC

Posted

技术标签:

【中文标题】实现 COM 接口 C++ / VC++ 6.0 / MFC【英文标题】:Implement COM interface C++ / VC++ 6.0 / MFC 【发布时间】:2011-09-29 19:45:40 【问题描述】:

这里的入门级程序员试图实现一个 COM 接口。我正在开发一个与 Aloha 销售点系统交互的程序。 Aloha 使用 COM 来处理外部程序。我正在尝试从 mag 读卡器截取卡数据,它是 OPOS 读卡器,而不是键盘楔。我的文档没有解释如何实现这个特定的接口,但它确实解释了如何实现一个类似的接口。我试图遵循这个例子,但我没有得到任何地方。不存在 Aloha 的支持,他们的文档很差、过时,有时甚至是错误的,即使我已经支付了许可证费用。

我尝试制作一个简单的应用程序来测试此功能。这是我所做的:

1) 使用 ATL COM 应用程序向导在 vc++ 6.0 中创建一个新项目 2)服务器类型dll 3) 插入新的 atl 对象 -> 简单对象 4)右键单击我的新类并选择实现接口 5) 浏览类型库,选择 Iber.tlb (Aloha's tlb) 6)选择我要实现的接口

生成了一个 .h、.cpp 和 .rgs 文件。

.h 文件有:

public:
// IInterceptMagcard
    STDMETHOD(InterceptMagcard)(BSTR bstrAccountNumber, BSTR bstrCustomerName, BSTR bstrExpirationDate, BSTR bstrTrack1Info, BSTR bstrTrack2Info, BSTR bstrTrack3Info, BSTR bstrRawMagcardData, LONG * bWasDataHandled)
    
        if (bWasDataHandled == NULL)
            return E_POINTER;

        return E_NOTIMPL;
    

那是我实现代码的地方吗?我在那里放了一些测试代码来写出一个txt文件来测试它。然后我用了:

HRESULT hr = CoCreateInstance(CLSID_AlohaMag, NULL, CLSCTX_INPROC_SERVER,
                                IID_IAlohaMag, (void **) &g_pIInterceptMagcard);

其中 g_pIInterceptMagcard 是指向我使用上述向导创建的接口类的指针。

当我尝试注册时,我得到以下 HRESULT:0x80040112 那就是“未经许可使用的类”。

这是否意味着我的程序没有创建必要的注册表项?

【问题讨论】:

这并不能解释您的问题,但是:g_pIInterceptMagcard 变量不应该是指向您的接口类的指针,因为CoCreateInstance 将用指向实现 CLSID_AlohaMag 的类的指针覆盖它。 @Frank:不太清楚你的意思。返回时,g_pIInterceptMagcard 将指向 AlohaMag 对象的 IAlohaMag 接口。我认为您的术语“接口类”并不明确,因为接口与实现的分离在 COM 中至关重要。 (没有“接口类”之类的东西。)返回的指针指向一个对象,而不是一个类。 (在 COM 或 C++ 中没有指向类的指针。) @ciaran:OP 说“其中 g_pIInterceptMagcard 是指向我使用上面的向导创建的接口类的指针”。我认为这意味着像 g_pIInterceptMagcard = new MyInterceptMagcard() 这样的东西是在 CoCreateInstance 调用之前执行的。我想指出的是,在调用 CoCreateInstance 之前分配 g_pIInterceptMagcard 的任何尝试都是浪费努力,因为 CoCreateInstance 用指向所请求接口的指针覆盖了最后一个参数(即 g_pIInterceptMagcard )的内容。 @Frank:啊,是的,我没有发现这是 Bob 的任期,而不是你的。对不起。 @Bob 更明确地说,如果您将g_pIInterceptMagcard 设置为 NULL,您应该会发现 CoCreateInstance still 返回错误。您的测试用例失败可能与您的 IInterceptMagcard 实现无关,您只是无法创建 CLSID_AlohaMag 类的实例。 【参考方案1】:

这可能意味着您必须先安装许可证,然后他们的自定义类工厂才能创建该类的实例。您是否尝试在完全正常工作的 POS 系统上运行您的程序,并获得使用许可的磁卡刷卡?也许您需要其他一些许可证才能执行此类操作?

如果是类未注册的问题,结果将是“类未注册”。听起来您已经通过向导完成了必要的步骤来实现接口并让它生成正确的注册表项。

【讨论】:

同意。我对许可控件不是很熟悉,但您可能需要将 CoCreateInstance 替换为对 CoGetClassObject(IClassFactory2) 和 IClassFactory2::CreateInstanceLic 的显式调用。 一般来说,你不需要这些。如果每个对象都需要一些额外的文档来描述如何创建对象的实例,那么 COM 就不能很好地工作。类工厂是通过对象的定义创建的,这通常是执行许可证的地方。 CoCreateInstance 是一个包装函数,它代表您调用 CoGetClassObject、IClassFactory::CreateInstance 和 IUnknown::QueryInterface。但 IClassFactory 不支持许可 - 为此您需要 IClassFactory2。 msdn.microsoft.com/en-us/library/ms690543%28v=VS.85%29.aspx。但更重要的是,Aloha 的作者可能使用了他自己的自定义许可方案,与标准 ActiveX 许可无关。 当你们说许可时,是在 COM 的上下文中还是您的意思是许可,例如我需要许可才能运行 Windows?如果是后者,是否意味着我正在测试的 POS 系统必须获得 Aloha 的许可? 是的,这是一个许可证问题。我的文档已经过时了。我必须使用 IClassFactory2 并提供许可证字符串才能使用该类。

以上是关于实现 COM 接口 C++ / VC++ 6.0 / MFC的主要内容,如果未能解决你的问题,请参考以下文章

编程软件:VC++6.0软件安装教程

初学c++,vc++6.0必备!

VC++ 6.0 →C++编译器

求救:到底GMP能不能在VC里面用?

VC++6.0

简述在VC++6.0环境下运行一个C++源程序的步骤