C#IConnectionPointContainer.FindConnectionPoint抛出异常

时间:2017-05-29 09:08:23

标签: c# callback com atl

我正在尝试使用连接点实现ATL COM模块。这个源代码几乎都是样板,我通过示例从 Developer's Workshop的第12章复制到了COM和ATL 3.0 由Andrew W. Troelsen。

这是很多代码,有三个源文件(几乎所有Visual Studio渲染样板文件)。

我认为我已经拥有了我需要的一切。有一个名为_IFooEvents_CP.h的子类来处理事件和类实现IConnectionPointImpl: 使用命名空间ATL;

template <class T>
class CProxy_IFooEvents : public IConnectionPointImpl<T, &__uuidof( _IFooEvents ), CComDynamicUnkArray>
{
    // WARNING: This class may be regenerated by the wizard
public:
        HRESULT Fire()
     {
     //...
     // event proxy code
     //...
     }

}

然后,在我的coclass的标题中(当然是Foo):

// Foo.h : Declaration of the CFoo

#pragma once
#include "resource.h"       // main symbols



#include "ConnectionPointTest_i.h"
#include "_IFooEvents_CP.h"



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif

using namespace ATL;


// CFoo

class ATL_NO_VTABLE CFoo :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CFoo, &CLSID_Foo>,
    public IConnectionPointContainerImpl<CFoo>,
    public IDispatchImpl<IFoo, &IID_IFoo, &LIBID_ConnectionPointTestLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    public CProxy_IFooEvents<CFoo>
{
public:
    CFoo()
    {
    }

DECLARE_REGISTRY_RESOURCEID(IDR_FOO)


BEGIN_COM_MAP(CFoo)
    COM_INTERFACE_ENTRY(IFoo)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CFoo)
    CONNECTION_POINT_ENTRY(__uuidof(_IFooEvents))
END_CONNECTION_POINT_MAP()

此外,idl文件已声明事件源,并且所有设置都归功于我用来制作此东西的ATL连接点向导:

library ConnectionPointTestLib
{
    importlib("stdole2.tlb");
    [
        uuid(25EAB56B-884A-4AA9-B470-BAA975E08343)      
    ]
    dispinterface _IFooEvents
    {
        properties:
        methods:
            [id(1), helpstring("test")] HRESULT bar();
    };
    [
        uuid(54B6050F-1090-4660-9DF0-D8A0853F96CF)      
    ]
    coclass Foo
    {
        [default] interface IFoo;
        [default, source] dispinterface _IFooEvents;
    };
};

所以,我有一个连接点容器接口的实现,我在连接点映射中有一个连接点,我已经在客户端声明了一个事件函数来实现。

编译时没有警告或错误。然后在C#方面我有以下内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using ConnectionPointTestLib;

namespace TestConnectionPoint
{
    class EventSink
    {
        public EventSink() { }
        public void bar()
        {
            Console.WriteLine("hello");
            Console.ReadLine();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {

                ConnectionPointTestLib.IFoo cpTest = new ConnectionPointTestLib.Foo();

                IConnectionPointContainer icpc;
                icpc = (IConnectionPointContainer)cpTest;
                IConnectionPoint icp;
                Guid id = typeof(Foo).GUID;

                icpc.FindConnectionPoint(ref id, out icp);


                EventSink es = new EventSink();
                int cookie;
                icp.Advise(es, out cookie);

                cpTest.testCP();
                Console.ReadLine();
            }
            catch (COMException e)
            {
                Console.WriteLine(e);
                Console.ReadLine();
            }
        }
    }
}

此行引发异常:

 icpc.FindConnectionPoint(ref id, out icp);

并且错误代码是异国情调:0x80040200。我无法在任何地方找到此代码,但我认为它不是正式的Windows代码。至少,我无法在MSDN的列表中找到它。

我从我在网上找到的一个例子中复制了客户端代码,所以可能是我错过了一步。

随后: 正如@Hans Passant指出的那样,错误代码是CONNECT_E_NOCONNECTION。我的理解是,这意味着接口没有暴露连接。但是,据我所知(我是这个游戏的新手)我已经做了我需要做的一切,以便在这里有一个输出接口。

我觉得我错过了一些神奇的小步骤。

0 个答案:

没有答案