欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于PB里 reference value readonly 3 种参数引用类型

程序员文章站 2022-03-29 20:26:18
本题目从一小段代码开始://====================================================================// Function: uo_tabpage_xml.of_print_xml_nodes//--------------------------------------------------------------------// 描述://-------------------------------------------....

本题目从一小段代码开始:

//====================================================================
// Function: uo_tabpage_xml.of_print_xml_nodes
//--------------------------------------------------------------------
// 描述: 
//--------------------------------------------------------------------
// 参数: 
//    readonly long al_count
//    readonly uo_xml_node ao_node[]    
//--------------------------------------------------------------------
// 返回:  integer
//--------------------------------------------------------------------
// 作者:    大自在(QQ781770213)        日期: 2020/07/15 14:29:42
//--------------------------------------------------------------------
//    CopyRight(c)
//--------------------------------------------------------------------
// 修改历史: 
//    
//====================================================================

long i,ll_count
uo_xml_node nodes[]
for i = 1 to al_count
    ll_count = ao_node[i].Get(ref nodes[])    
    lb_1.additem("a")
    of_print_xml_nodes(ll_count,nodes[])
next
return 1
       这个题目,就从这段代码开始。这段代码,它就是一个递归,里面用到了 我写的一个对象 uo_xml_node。开始的时候,参数引用类型使用了 value,程序一运行,就崩溃,后来把参数类型改为 readonly ,就一切正常了。于是对以前没多注意的参数引用类型做了一些思考,想清楚了个中原因。

     由于PB是由C++开发的,站在这个角度,我们先来看看PB的参数是个什么东东。先看一个数据结构:

     struct ob_data
       {
            OB_VALUE               val;
            OB_INFO_FLAGS        info;                    // Data node info flags
            OB_CLASS_ID            type;                    // Data Type

        };

    这个 ob_data,就是PB的参数,PB的每一个变量,int ,long,window.... 所有类型,其实在PBVM里,都是这样的一个 ob_data。它的 type 指明了是一个什么类型,比如 1 是 int,2是long,6是string,大于22的基本上就是对象。

具体到 OB_VALUE这个,它是一个union,可以是指针,可以是普通变量。info这个值,它有各种指示,非常复杂,暂时不管它。

 假如有一个参数 ob_data myarg;

  1、reference引用:

    它实际上是这样的:
   ob_data value;
myarg.info= 我是一个引用
myarg.ob_value = &myarg;
明白了吧,它是一个结构,再套一个指针,实际使用时,指的是ob_value里的指针。

  2、valu引用:

 copy myarg myargClonc;

也就是原封不动地将原结构,复制了一份,里面的内容不动,然后修改里面的 myargClone.info 后,传递给程序。

3、readonly引用:

这个它就简单了,直接传的是 &myarg;

说到这里,咱们回到今天的主题上。为什么我直接用 value 传参数会崩溃呢?

原因是:每一个uo_xml_node的内部,我对应了一个C++对象的指针,在对象 destroy 时,做了 delete 指针操作。所以 value 引用时,因为clone了另一个结构,2个结构里面的指针一样,指向同一个C++对象,被 delete 了2次,所以程序出问题了。而readonly只是传 &myarg ,不会导致我内部的C++对象被2次 delete。

问题想明白了。吸取一个经验教训:凡我在 pbjson.dll 里写的这些对象,作为参数引用时,都要用 readonly 方式,不要使用value方式。

另外说一点,是不是用  readonly 就省事安全呢?其实也未必 。因为PB里面,它每一个线程都有自己独立 的堆管理。它的变量是不允许跨堆 使用的,否则程序会崩溃。 这也是PB里为什么各线程之间的变量不能互相访问的根本 原因。跨线程传参数,是必须要用 value 的,它会由各自线程在自己堆上建立新的变量。甚至有些同一线程内部因为变量生命周期的原因,也需要用 value方式,否则 用 readonly 方式得到的 &myarg 指针,有可能是无效的指针,导致程序出问题。

当然,同一线程内,内部不是把对象和指针绑定的情况下,传 readonly和 value,没多大区别,copy 一个 ob_data 的性能差别,可以忽略不计。

本文地址:https://blog.csdn.net/lxbin2003/article/details/107360085

相关标签: PB PB应用技术