我正在尝试从Microsoft(link to the source)编译以下COM / ActiveX示例,但是我遇到了一些我无法修复的错误:
// evh_server.h
#pragma once
[dual, uuid("00000000-0000-0000-0000-000000000001")]
__interface IEvents {
[id(1)] HRESULT MyEvent([in] int value);
};
[dual, uuid("00000000-0000-0000-0000-000000000002")]
__interface IEventSource {
[id(1)] HRESULT FireEvent();
};
class DECLSPEC_UUID("530DF3AD-6936-3214-A83B-27B63C7997C4") CSource;
// evh_server.cpp
// compile with: /LD
// post-build command: Regsvr32.exe /s evh_server.dll
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include "evh_server.h"
[module(dll, name = "EventSource", uuid = "6E46B59E-89C3-4c15-A6D8-B8A1CEC98830")];
[coclass, event_source(com), uuid("530DF3AD-6936-3214-A83B-27B63C7997C4")] // <-- Error C3745: 'void VariantInit(VARIANTARG *)': only an event can be 'raised'
class CSource : public IEventSource {
public:
__event __interface IEvents; // <-- Error: interface types cannot be nested class types
HRESULT FireEvent() {
__raise MyEvent(123); // <-- Error: identifier "MyEvent" is undefined
return S_OK;
}
};
// evh_client.cpp
// compile with: /link /OPT:NOREF
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <stdio.h>
#include "evh_server.h"
[module(name = "EventReceiver")];
[event_receiver(com)]
class CReceiver {
public:
HRESULT MyHandler1(int nValue) {
printf_s("MyHandler1 was called with value %d.\n", nValue);
return S_OK;
}
HRESULT MyHandler2(int nValue) {
printf_s("MyHandler2 was called with value %d.\n", nValue);
return S_OK;
}
void HookEvent(IEventSource* pSource) {
__hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
__hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
}
void UnhookEvent(IEventSource* pSource) {
__unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
__unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
}
};
int main() {
// Create COM object
CoInitialize(NULL);
{
IEventSource* pSource = 0;
HRESULT hr = CoCreateInstance(__uuidof(CSource), NULL, CLSCTX_ALL, __uuidof(IEventSource), (void **)&pSource);
if (FAILED(hr)) {
return -1;
}
// Create receiver and fire event
CReceiver receiver;
receiver.HookEvent(pSource);
pSource->FireEvent();
receiver.UnhookEvent(pSource);
}
CoUninitialize();
return 0;
}
另一个错误:
atlbase.h(2835):错误C2338:&#39; CAtlDllModuleT&#39;必须使用 _WINDLL或_USRDLL定义
由于此代码应该是正确的(我没有修改它),问题可能在于我尝试构建它的方式。
传递选项/ LD和/ link我得到不同的错误(选项/ OPT:NOREF无法识别,/ link需要源文件名)。
平台:Microsoft Visual C ++ 12.0
答案 0 :(得分:1)
这是工作代码,它被混洗到单个源代码文件(控制台应用程序)中:
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <atlstr.h>
[dual, uuid("00000000-0000-0000-0000-000000000001")]
__interface IEvents
{
[id(1)] HRESULT MyEvent([in] int value);
};
[dual, uuid("00000000-0000-0000-0000-000000000002")]
__interface IEventSource
{
[id(1)] HRESULT FireEvent();
};
class DECLSPEC_UUID("530DF3AD-6936-3214-A83B-27B63C7997C4") CSource;
[coclass, event_source(com), uuid("530DF3AD-6936-3214-A83B-27B63C7997C4")]
class CSource : public IEventSource
{
public:
__event __interface IEvents;
HRESULT FireEvent()
{
__raise MyEvent(123);
return S_OK;
}
};
[event_receiver(com)]
class CReceiver
{
public:
HRESULT MyHandler1(int nValue)
{
printf_s("MyHandler1 was called with value %d.\n", nValue);
return S_OK;
}
HRESULT MyHandler2(int nValue)
{
printf_s("MyHandler2 was called with value %d.\n", nValue);
return S_OK;
}
void HookEvent(IEventSource* pSource)
{
__hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
__hook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
}
void UnhookEvent(IEventSource* pSource)
{
__unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler1);
__unhook(&IEvents::MyEvent, pSource, &CReceiver::MyHandler2);
}
};
[ module(type=exe, name="Event") ];
int _tmain(int argc, _TCHAR* argv[])
{
// Create COM object
CoInitialize(NULL);
{
CComObject<CSource>* pSource = NULL;
ATLVERIFY(SUCCEEDED(CComObject<CSource>::CreateInstance(&pSource)));
CComPtr<IEventSource> pEventSource = pSource;
CReceiver Receiver;
Receiver.HookEvent(pEventSource);
pSource->FireEvent();
Receiver.UnhookEvent(pEventSource);
}
CoUninitialize();
return 0;
}