检查COM指针的存在 [英] Check existence of COM pointer

查看:110
本文介绍了检查COM指针的存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

在c ++中,MFC:

我有一个CComPointer:

CComPointer<IMyTask>				m_pTask;	



我的代码中有很多地方,我调用此ComPointer来运行任务的方法.例如:

  void  method1()
 {
    如果(失败(hRet = m_pTask-> MyFunc1()))
                  .....
 }

无效 method2()
{
    如果(失败(hRet = m_pTask-> MyFunc2()))
                  .....
} 




我尝试解决MyTask关闭时要恢复的问题.
我写了一个方法restore(),将CoCreate重新运行到MyTask,它实际上解决了这个问题.

我可以看到,如果MyTask已死,我得到的HR失败代码为-2147023174,则RPC服务器不可用.但是,com指针m_pTask具有完整的数据(它不知道任务已死).

我可以做这样的事情:

  void  method1()
 {
    如果(失败(hRet = m_pTask-> MyFunc1()))
        如果(hRet ==- 2147023174 )
           恢复();
                  .....
 }

无效 method2()
{
    如果(失败(hRet = m_pTask-> MyFunc2()))
        如果(hRet ==- 2147023174 )
           恢复();
                  .....
} 




但是,因为我有很多通过compointer调用方法的方法,所以我想做一些更通用的事情.
我希望每次我尝试通过ComPointer在运行该方法之前运行一种方法时,都要检查该任务是否已经存在,如果不存在,请运行该方法.
由于即使任务完成了,ComPointer仍然拥有来自CoCreate的所有数据,所以我不知道该怎么办.

我该怎么办?

由于系统中发生了一些错误,任务已死,现在我的解决方案不需要找到任务失败的原因,只需恢复即可.我正在寻找一个通用的解决方案-像ComPointer的包装器一样,但是我希望包装器类仅检查MyTask是否仍然存在,如果是-它将返回ComPointer,如果不存在,它将运行restore .

我该怎么办?

谢谢

解决方案

起初,a将使用-2147023174的定义值来提高代码质量.

将布尔值用于最后一个已知的运行状态.这会激发性能,因为它不需要调用某些COM开销.


您需要一些透明地捕获错误并执行一些恢复操作的功能,这听起来像是代理对象的工作. br/>
基本上,就恢复透明度而言,您当前的界面并没有完全削减它.这里的想法是,您在一个包含(代理)对象中再次实现您的接口,该对象将调用传递到处理任何出现的错误的真实对象,而所有这些调用者都不知道.

假设您有一个接口A,它只有一个成员,即f:

  class  A
{
    公共:
        虚拟 布尔 f()=  0 ;
}; 

的想法是f会做一些有用的事情,如果出现问题则返回false.这等效于您的COM接口.

您已经在B ...

  class  B中实现了此接口: public  A
{
    公共:
        虚拟 布尔 f();
}; 

这相当于您的CoClass.问题是f经常返回false,并且您的代码充满杂乱无章,例如:

  void  do_something(A * ptr)
{
    如果(!ptr&&!ptr-> f())
    {
        do_remedial_action();
    }
} 

使用一个功能就可以了,但是请等到您在界面上实现更多功能!

那么如何隐藏整个问题呢?

1.声明一个新类,即一个代理,该类实现A:

  class  recoveryable_proxy_for_A: public  A
{
    公共:
        虚拟 布尔 f()
        {
            返回 ;
        }
}; 

不做很多事情吗?挂在那里!

2.为recoverable_proxy_for_A添加一个构造函数,该构造函数采用实现A的对象的实例: >公共 A { 公共: recoveryable_proxy_for_A(A * to_be_proxied) :proxied_(to_be_proxied) 虚拟 布尔 f() { 返回 ; } 私有: *代理_; };

3.调用包含的A:

  class  recoveryable_proxy_for_A:公共:
        recoveryable_proxy_for_A(A * to_be_proxied)
            :proxied_(to_be_proxied)

        虚拟 布尔 f()
        {
            返回 proxied _-> f();
        }

    私有:
        *代理_;
}; 

4.最后在其中添加魔术内容.处理对recoveryable_proxy_for_A :: f:

  class 的调用中的错误="code-keyword">公共 A
{
    公共:
        recoveryable_proxy_for_A(A * to_be_proxied)
            :proxied_(to_be_proxied)

        虚拟 布尔 f()
        {
            如果(!proxied _-> f())
            {
                do_remedial_action();
                返回 proxied _-> f(); // 也许再试一次?
            }

            返回 ;
        }

    私有:
        *代理_;
}; 

您可以将在代码中实现A的实例的每次使用替换为recoveryable_proxy_for_A,并且错误检查会自动进行.


Hello,

In c++, MFC:

I have a CComPointer:

CComPointer<IMyTask>				m_pTask;	



there are a lot of places in my code, I call to this ComPointer to run the task''s methods. For example:

void method1()
 {
    if (FAILED(hRet = m_pTask->MyFunc1()))
                  .....
 }

void method2()
{
    if (FAILED(hRet = m_pTask->MyFunc2()))
                  .....
}




I try to solve a problem to recover when MyTask is down.
I wrote a method, recover(), that rerun the CoCreate to MyTask, and it actually solves the problem.

I could see that if MyTask is dead, i get an HR fail code of -2147023174, RPC server is unavailable. But, the com pointer m_pTask has the full data (it doesn''t know the task is dead).

I can do something like this:

void method1()
 {
    if (FAILED(hRet = m_pTask->MyFunc1()))
        if (hRet == -2147023174)
           recover();
                  .....
 }

void method2()
{
    if (FAILED(hRet = m_pTask->MyFunc2()))
        if (hRet == -2147023174)
           recover();
                  .....
}




But, because I have alot of calling to methods via the compointer, I want to make something more general.
I want that everytime I try to run a method via the ComPointer, before the runnuing of the method, to check that the task is already exists, and if not - run the recover method.
Since even when the task is dead, ComPointer still has all the data from the CoCreate time, I don''t know how can I do it.

How can I do it?

The task is dead due to an error that occurs sometiems in the system, and for now my solution does not need to find the reason for the task failure, just to recover it. I am looking for a general solution - like a wrapper to the ComPointer, but I want that the wrapper class will only check if MyTask is still exists, and if it is -it will return the ComPointer, and if not, it will run recover.

How can I do it?

Thanks

解决方案

At first a would use the define-value of -2147023174 to enhance code quality.

Use a bool for the last known running state. That fires up perfomance because it doesnt need to call some COM-overhead.


You need something to catch errors transparently and do some recovery action, it sounds like a job for a proxy object.

Bascially your current interface doesn''t quite cut it as far as transparency of recovery goes. The idea here is that you implement you interface again in a containing (proxy) object that passes calls through to the real object handling any errors that come out, all without the caller knowing.

Say you have an interface A, it''s got one member, f:

class A
{
    public:
        virtual bool f() = 0;
};

The idea is that f does something useful, returning false if something breaks. This is the equivalent of your COM interface.

You''ve implemented this interface in B...

class B : public A
{
    public:
        virtual bool f();
};

This is the equivalent of your CoClass. The problem is that f''s returning false a bit too often and your code is full of chaff like:

void do_something( A *ptr )
{
    if( !ptr && !ptr->f() )
    {
        do_remedial_action();
    }
}

It''s okay with one function, but wait until you implement some more on your interface!

So how can you hide the whole problem?

1. Declare a new class, a proxy, which implements A:

class recoverable_proxy_for_A : public A
{
    public:
        virtual bool f()
        {
            return false;
        }
};

Doesn''t do a lot does it? Hang in there!

2. Add a constructor for recoverable_proxy_for_A which takes an instance of an object implementing A:

class recoverable_proxy_for_A : public A
{
    public:
        recoverable_proxy_for_A ( A *to_be_proxied )
            : proxied_( to_be_proxied )

        virtual bool f()
        {
            return false;
        }

    private:
        A *proxied_;
};

3. Implement recoverable_proxy_for_A by calling through to the contained A:

class recoverable_proxy_for_A : public A
{
    public:
        recoverable_proxy_for_A ( A *to_be_proxied )
            : proxied_( to_be_proxied )

        virtual bool f()
        {
            return proxied_->f();
        }

    private:
        A *proxied_;
};

4. Finally add the magic thing bit in... Handle the error in the call to recoverable_proxy_for_A::f:

class recoverable_proxy_for_A : public A
{
    public:
        recoverable_proxy_for_A ( A *to_be_proxied )
            : proxied_( to_be_proxied )

        virtual bool f()
        {
            if( !proxied_->f() )
            {
                do_remedial_action();
                return proxied_->f(); // try again perhaps?
            }

            return true;
        }

    private:
        A *proxied_;
};

The you can replace every use of instance of something implementing A in your code with recoverable_proxy_for_A and your error checking happens automagically.


这篇关于检查COM指针的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆