无法编译Microsoft COM / ActiveX示例

时间:2014-08-29 16:04:36

标签: c++ visual-c++ com activex

我正在尝试从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需要源文件名)。

  • 我是否被迫生成DLL?
  • 我该如何建立这个项目?
  • 代码中的那些大数字真的有必要吗?

平台:Microsoft Visual C ++ 12.0

1 个答案:

答案 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;
}

或者,您可以使用VS2012项目文件(SVNTrac)获取它。