CORBA / OMG C ++ 11语言映射

时间:2013-06-05 13:39:05

标签: c++ c++11 standards corba idl

我目前正致力于[OMG13](符合以下标准)兼容的C ++ 11部分外观,以适应遗留(C ++)ORB;在服务器端,没有DII,没有OBV等意义上的“部分” - 因此只是非常基本的东西。

[OMG13]在 6.25.6 基于继承的接口实现

  

必须基于生成的基类派生   OMG IDL接口定义。 生成的基类是已知的   作为骨架类,派生类称为   实施课程。接口的每个操作都有一个   在骨架类中声明的相应虚拟成员函数。

[强调我的]

如果按照字面意思理解,那意味着,对于idl中定义的接口A,A_impl应该是A_skel的后代

class A_impl : /* whatever, likely public */  A_skel {
    /**/
};

6.25.6 中给出的片段另有说明

// C++
class A_skel : public virtual CORBA::servant_traits<A>::base_type { ... };
// C++
class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

所以,根据这些片段,A_impl和A_skel是兄弟姐妹,从同一个祖先下降。


决定做什么并不容易,因为前者的标准,C ++ 11之前的C ++,映射[OMG12], 5.40.3 基于继承的接口实现

  

可以基于OMG IDL接口定义从生成的基类派生实现类。生成的基类称为骨架类,派生类称为实现类。

所以对于C ++来说,“可以”不是“必须”,在C ++ 11之前,映射,并且给出的片段与此“can”一致

class POA_A : public virtual PortableServer::ServantBase 
{
    /* [...] */
}

/* [...] */

class A_impl : public POA_A
{
   /* [...] */
};

这也是我使用的传统ORB基础架构的构建(除了还提供基于委托的[OMG12]协议实现)。


那么 - 如何将我的小c ++ 11兼容ORB门面中的_skel和_impl与[OMG13]兼容并强化impl代码以防止可能重构[OMG13]的那部分?

一个人可以,例如考虑从CRTP样式的继承多路复用类派生_impls:

struct Snippet_Reading{};
struct Prose_Reading{};

namespace mock {

    class IA{}; 

    // impl specific, not important here  
    template<class Ifc>
    struct LoremIpsum {}; 


    template<class Ifc>
    class POA_Delegator {
         // impl specific, not important here  
    };

    namespace CORBA {
        template<class Ifc>
        struct servant_traits {
            /// @TODO meditate how to implement that
            typedef LoremIpsum<Ifc> base_type;
        };
    }
} 

namespace detail {
    using namespace mock;

    template<typename Reading, class Ifc>
    class Base {};

    template<class Ifc>
    class Base<Prose_Reading, Ifc> : public virtual POA_Delegator<Ifc> {};

    template<class Ifc>
    class Base<Snippet_Reading, Ifc> : public virtual CORBA::servant_traits<Ifc>::base_type {};
}

#if defined(PROSE_READING)
    template <class Ifc>
    using Base = detail::Base<Prose_Reading, Ifc>;
#elif  defined(SNIPPET_READING)
    template <class Ifc>
    using Base = detail::Base<Snippet_Reading, Ifc>;
#else
    #error Oh My Goodness! Don't know how to interpret OMG's IDL to C++11 Mapping!
#endif 


class IA_impl : public virtual Base<mock::IA> {};


int main() {}

但这并不完全是符合标准的实现者的接口。

参考

[OMG12] OMG C ++语言映射。 OMG,2012。http://www.omg.org/spec/CPP/1.3

[OMG13]天啊。 C ++ 11语言映射。 OMG,2013。http://www.omg.org/spec/CPP11/

2 个答案:

答案 0 :(得分:1)

CORBA :: servant_traits :: base_type应该在编译时解析为A_skel。用户并没有真正看到A_skel,这只是一个实现细节。用户定义的A_impl不仅仅是从CORBA :: servant_traits :: base_type trait派生的。

正如您所指出的,6.26.6中存在错误。骨架类应该相互派生,而不是来自特征,所以它应该如下,C_skel也缺乏。

// C++
class A_skel : public virtual PortableServer::ServantBase {};
class B_skel : public virtual A_skel {};
class C_skel : public virtual A_skel {};
class D_skel : public virtual B_skel, public virtual C_skel {};

对于草案V1.1映射,请参阅http://osportal.remedy.nl。我们也可以帮助您解决问题,请随时与我联系。

您是否可以向OMG报告6.26.2中示例的正式问题,以便我们可以在规范的V1.2版本中解决该问题

答案 1 :(得分:0)

回应Johnny Willemsen的回答:

好的,让我们将各个部分捆绑在一起:

标准要求

class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

如果这个

  

CORBA :: servant_traits :: base_type应该在编译时解析为A_skel。

应该按照这种方式定义A_skel

class A_skel : public virtual PortableServer::ServantBase {};

然后必须有template<T>struct CORBA::servant_traits的A的专门化,所以我认为,标准应该暗示这种依赖:

class A {
  public:
    virtual long foo() = 0;
};

namespace mock {

    namespace CORBA {
        template<class Ifc>
        struct servant_traits { /* ? */};
    }

    namespace PortableServer {
        class ServantBase { /* ... */};
    }
} 

using namespace mock;

class A_skel : public virtual PortableServer::ServantBase {
    virtual long foo() = 0;
};

namespace mock {
    namespace CORBA {
        template<>
        struct servant_traits<A> {
            typedef A_skel base_type;
            // ...
        };
    }
}    

class A_impl : public virtual CORBA::servant_traits<A>::base_type {
  public:
    virtual long foo() {
        return 42;
    }
};

int main() {}

我能做到这一点吗?