第一范文网 - 专业文章范例文档资料分享平台

基于TAO(The ACE ORB)的CORBA编程

来源:用户分享 时间:2025/7/15 6:23:32 本文由瀛ゅ績鏃犳剰 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

? _this

该方法返回当前对象的拷贝的引用。 ? _add_ref/_remove_ref

用于增加引用计数和减小引用计数,在我们编写接口实现时可能会用到(客户程序中无法使用这两个方法,因为只有Skeleton代码中会生成这两个方法,客户程序代码也没有必要使用这两个方法来维护引用计数)。

此外,在CORBA命名空间中还定义了: ? CORBA::is_nil 判断某个ptr是否为空 ? CORBA::release

释放参数对象。

而为了比较两个引用是否相同,CORBA::Object中定义了方法: ? is_equivalent

按照CORBA规范,不使用以上基本方法对CORBA对象或对象指针进行比较、类型转换、非空测试等所产生的行为都是未定义的。

这几个方法本身比较简单,并且后续的文章中将看到上述各基本方法的使用,这里就先不举例了。

二、_var智能指针类中的基本方法

按照CORBA规范,每个_var智能指针类都包括如下几个方法: ? in ? out ? inout ? _retn

? ptr

掌握这几个方法的最简单的方法是学习CORBA::String_var类的实现。CORBA::String_var是CORBA::String类的智能指针类,其中封装了一个char*指针。我们来看看TAO是如何实现这几个方法的(见%TAO_ROOT%/tao/CORBA_String.inl):

ACE_INLINE const char *

CORBA::String_var::in (void) const {

return this->ptr_; }

ACE_INLINE char *&

CORBA::String_var::inout (void) {

return this->ptr_; }

ACE_INLINE char *&

CORBA::String_var::out (void) {

CORBA::string_free (this->ptr_); this->ptr_ = 0; return this->ptr_; }

ACE_INLINE char *

CORBA::String_var::_retn (void) {

char *temp = this->ptr_; this->ptr_ = 0; return temp; }

/// TAO extension.

ACE_INLINE char *

CORBA::String_var::ptr (void) {

return this->ptr_; }

表面看来似乎没有什么值得注意的,只是返回了几个不同类型的指针:in方法返回一个指针(因仅作为传入参数),inout方法返回一个指针的引用(因不仅要作我传入参数,还要通过函数调用修改其内容),out方法同样返回一个指针的引用(因需要通过函数调用修改其内容),inout方法返回一个指针(因仅作为返回参数,不能修改),ptr也返回一个普通指针,同样也不能修改内容。

但仔细看一看_retn的实现,你会发现,该方法首先保存了指针的内容,然后将指针清0(这样当String_var被释放时就不会free原来的地址空间),最后将该指针返回。也就是说,通过该方法调用,String_var对象所指向的地址空间的控制权被交给了调用该方法的一方,同样,释放地址空间的工作也应该由调用该方法的一方来完成。

而对于out方法,为了保证原指针被安全释放,该方法先释放原来指向的地址空间,并将指针清0,最后返回该指针的引用。因此,被调用的方法内部应负责为该对象分配空间,而释放该空间的工作则是由调用方完成的。 其他对象上述方法的实现与String_var在原理上是基本一致的,只是IDL编译器tao_idl在生成stub和skeleton代码时会分别为定长结构体和变长结构体应用不同的类模板,从而生成不同类型的_var类。对于定长结构体,应用的类模板为TAO_Fixed_Var_T,而对于变长结构体,应用的类模板为TAO_Var_Var_T。二者的区别在于对于定长结构体而言,_retn和out方法与inout方法的实现是一样的,没有清0的过程,以下是TAO_Fixed_Var_T模板类中的相关代码:

// Mapping for fixed size. template ACE_INLINE

T &

TAO_Fixed_Var_T::out (void) {

return *this->ptr_; }

template ACE_INLINE

T

TAO_Fixed_Var_T::_retn (void) {

return *this->ptr_; }

关于_var类的更多信息,可参考%TAO_ROOT%/tao/VarOut_T.inl,或:

http://www.dre.vanderbilt.edu/Doxygen/Current/html/tao/classTAO__Var__Var__T.html http://www.dre.vanderbilt.edu/Doxygen/Current/html/tao/classTAO__Fixed__Var__T.html

三、典型问题解析

上面简单介绍了CORBA编程中常用的几个基本方法,下面在此基础上对内存管理相关的几个问题进行简要分析。

? 包含变长成员变量的结构体的内存释放问题 以下面的idl为例:

struct DemoStruct { string name_; };

对于如下的代码:

int main() { }

由于我们使用了_var智能指针类,通过new动态分配的空间会在demo对象被销毁时被释放,但是其中通过CORBA::string_dup为成员变量name_所分配的空间是否会泄漏呢?

答案是:不会。这是因为idl文件中结构体的string成员变量经过tao_idl编译后,被映射为TAO_String_Manager,这种类型与String_var基本是一样的,只是String_var不带任何参数的构造函数会将指针ptr_初始化为0,而TAO_String_Manager不带任何参数的构造函数则会将ptr_初始化成一个空字符串,具体可见%TAO_ROOT%/tao/Managed_Types.i及%TAO_ROOT%/tao/CORBA_String.inl。

因此,当结构体被释放时,我们就无需为其中的string的释放问题担心。对于其它包含变长类型的结构体而言,情况是一样的。

? _var类使用的误区 在使用

String_var

时有一个问题需要注意,String_var

提供了三个构造函数

//...

DemoStruct_var demo = new DemoStruct; demo.name_ = CORBA::string_dup(\); //...

(见%TAO_ROOT%/tao/CORBA_String.h):

CORBA::String_var::String_var (char *p) : ptr_ (p) { }

ACE_INLINE

CORBA::String_var::String_var (const char *p) : ptr_ (CORBA::string_dup (p)) { }

CORBA::String_var::String_var (const CORBA::String_var& r) {

this->ptr_ = CORBA::string_dup (r.ptr_); }

第一个构造函数仅对指针p进行浅拷贝,保存到内部的ptr_中,而后面两个则通过深拷贝来构造String_var对象。

两种不同的构造方式区别虽然比较小,但可能引起一些十分隐蔽的问题。如下面的代码就存在问题:

String_var str(\);

因为上述代码会使用第一个而不是第二个构造函数来构造str,从而使得str获得静态地址空间\的控制权,并在str被析构时尝试释放该空间,这显然是错误的。要避免该错误,我们应该总是强制使用第二个构造函数,或在构造Stirng_var对象前主动复制String的内容,如:

String_var str1((const char*)\);

String_var str2(CORBA::string_dup(\));

除非你清楚地知道第一个构造函数是你需要的。 对于其它_var类型而言,不存在与上面第二种构造方式等价的构造函数,我们总是使用第一种形式的构造函数,即新构造的_var对象会获得指针的控制权。

与上面第三种构造方式类似,如果你传入的是一个_var引用,则使用的是如下的构造函数:

template

TAO_Var_Base_T::TAO_Var_Base_T (const TAO_Var_Base_T & p) : ptr_ (p.ptr_ ? new T (*p.ptr_) : 0) { }

该构造函数会对传入的_var引用进行深拷贝。 ? 对远程方法调用内存管理问题的解释

CORBA内存分配/释放的原则很简单:各自负责自己分配空间的释放,C/S两端内存的分配与释放(以及更新)不会自动通知另一方。

对于Client代码而言,由Client代码负责释放的空间还包括ORB在unmarshalling期间创建的Server的指针的镜像,即Server端指针的本地拷贝,这些空间可能是out/inout参数或者作为接口方法的返回值通过方法调用获得的。

这在理解上应该没有什么问题。但是,其中对于Server方的内存管理,我们没有考虑。以如下代码为例:

DemoStruct* DemoIntf::foo() {

DemoStruct_var var = new DemoStruct;

搜索更多关于: 基于TAO(The ACE ORB)的CORBA编程 的文档
基于TAO(The ACE ORB)的CORBA编程.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c1aadi12imx4yj364r8xn_4.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top