C/C++单元测试工具Visual Unit 4在线帮助


数字转换为指针

自V4.6开始,数字转指针已实现自动处理,使用方法:工程属性》高级》替换》数字地址转为合法指针,选中“自动处理”。如自动处理产生问题,请阅读以下手动处理说明。

问题场景
    部分嵌入式项目,变量地址由数字指定,将数字直接作为指针使用,常见方式类似于以下代码:

    typedef struct ObjectType
    {
        int a;
        int b;
    }ObjectType;

    //基地址
    #define BASE_ADDR 0x200000

    //以基地址加偏移定义的基础类型指针,只需转换基地址。
    #define Mem01 ((int*)(BASE_ADDR + 0x100)) //指针1
    #define Mem02 ((int*)(BASE_ADDR + 0x200)) //指针2

    //直接用数字定义的基础类型指针,需各自转换
    #define Mem03 ((int*)(0x00200100))
    #define Mem04 ((int*)(0x00200200))

    //以基地址定义的复合类型指针,需各自转换
    #define objData1 ((ObjectType*)(BASE_ADDR + 0x1000))
    #define objData2 ((ObjectType*)(BASE_ADDR + 0x2000))

    //直接用数字定义复合类型指针,需各自转换
    #define objData3 ((ObjectType*)0x00300100)
    #define objData4 ((ObjectType*)0x00300200)

    以上,Mem01、Mem02、Mem03、Mem04,作为int*类型指针使用,objData1、objData2、objData3、objData4,作为ObjectType*类型指针使用。执行测试过程中,对这些指针进行读或写操作的代码行将崩溃。

解决办法
    工程属性》高级》替换》数字地址转为合法指针,点击“添加”,如下图:

   
 
只需转换基地址的情形:
    如果一系列地址是在一个基地址的基础上,加上偏移量来定义的,且为基本数据类型,则只需转换基地址,不必处理每个地址,如:
    #define BASE_ADDR 0x200000 //基地址
    #define Mem01 ((int*)(BASE_ADDR + 0x100)) //指针1
    #define Mem02 ((int*)(BASE_ADDR + 0x200)) //指针2
    ......
    只需转换BASE_ADDR,无需转换Mem01、Mem02。
    此种情形下,需注意:
    1)“替换为”不能手工修改。
    2)“元素数”必须足免够大,以保证最大的地址有效。

标记

    填写宏名称,如Mem03、objData1。对于只需转换基地址的情形,“标记”填写基地址的宏名。

数据类型
    只能填写基本数据类型,且不含指针符号,如char、unsigned char、int,具体的类型要满足两个条件之一:
    1)与宏义一致,如#define Mem01 ((int*)(BASE_ADDR + 0x100)),则数据类型为int,这种情形下,“替换为”输入框不需要手工填写,使用自动填写的内容即可。
    2)可以转换为目标类型,如#define objData1 ((ObjectType*)(BASE_ADDR + 0x1000)),数据类型可以使用unsigned charcharshortint等,这种情形下,“替换为”输入框需要手工修改,加入类型转换代码。

元素数
    如果需要一大块的内存,应使用数组,这里填写数组的元素数,支持10进制和16进制。

变量名
    用于生成变量定义Var,形成有效的内存空间。

指针名
    用于生成指针变量,指向Var的地址,形成有效的指针,以代替原来的数字。

替换为
    用于将代码中使用的数字指针替换为有效指针,填写时,可拷贝宏定义中宏名称后的内容,并将其中的数字改为指针名。如果不需要类型转换,此项可使用自动填写的内容。
    如:#define Mem03 ((int*)(0x00200100)),指针名为_Mem03,则替换为填写:((int*)_Mem03);
    如:#define objData3 ((ObjectType*)0x00300100),指针名为_objData3 ,则替换为填写:((ObjectType*)_objData3)。

加入表格
    完成转换后,“指针名”相当于一个普通的全局变量,可以加入表格并设置输入和判断输出。

自动生成的代码示例
    添加转换后,VU自动生成变量定义以及指针定义,如:

    //VuxInc/VuxNpi.h(实现)
    int __BASE_ADDR[0x1000] = {0};
    int* _BASE_ADDR = &__BASE_ADDR[0];

    int __Mem03 = 0;
    int* _Mem03 = &__Mem03;

    int __Mem04 = 0;
    int* _Mem04 = &__Mem04;

    int __objData1 = 0;
    int* _objData1 = &__objData1;

    int __objData2 = 0;
    int* _objData2 = &__objData2;

    unsigned char __objData3[0x1000] = {0};
    unsigned char* _objData3 = &__objData3[0];

    unsigned char __objData4[0x1000] = {0};
    unsigned char* _objData4 = &__objData4[0];

    //VuxInc/VuxNpd.h(声明)
    extern int* _BASE_ADDR;
    extern int* _Mem03;
    extern int* _Mem04;
    extern int* _objData1;
    extern int* _objData2;
    extern unsigned char* _objData3;
    extern unsigned char* _objData4;

自动替换的代码示例
    红色为原始代码,紫红色为替换后的代码。
    int _13_NumberPointer(int a, int b)
    {
        int ret = 0;

        //基地址
        //#define BASE_ADDR 0x200000
        //以基地址加偏移定义的基础类型指针,只需转换基地址。
        //#define Mem01 ((int*)(BASE_ADDR3 + 0x100)) //指针1
        //#define Mem02 ((int*)(BASE_ADDR3 + 0x200)) //指针2

        *Mem01 = a;
        *Mem02 = b;
        ret += *Mem01;
        ret += *Mem02;

        *((int*)( _BASE_ADDR + 0x100)) = a;
        *((int*)( _BASE_ADDR + 0x200)) = b;
        ret += *((int*)( _BASE_ADDR + 0x100));
        ret += *((int*)( _BASE_ADDR + 0x200));


        //直接用数字定义的基础类型指针,需各自转换
        //#define Mem03 ((int*)(0x00200100))
        //#define Mem04 ((int*)(0x00200200))

        *Mem03 = a;
        *Mem04 = b;
        ret += *Mem03;
        ret += *Mem04;

        * _Mem03 = a;
        * _Mem04 = b;
        ret += * _Mem03;
        ret += * _Mem04;


        //以基地址加偏移定义的复合类型指针,需各自转换
        //#define objData1 ((ObjectType*)(BASE_ADDR + 0x1000))
        //#define objData2 ((ObjectType*)(BASE_ADDR + 0x20
00))
        objData1->a = a;
        objData2->a = b;
        ret += objData1->a;
        ret += objData2->a;

        ((ObjectType*)(_objData1))->a = a;
        ((ObjectType*)(_objData2))->a = b;
        ret += ((ObjectType*)(_objData1))->a;
        ret += ((ObjectType*)(_objData2))->a;


        //直接用数字定义的复合类型指针,需各自转换
        //#define objData3 ((ObjectType*)0x00300100)
        //#define objData4 ((ObjectType*)0x00300200)

        objData3->a = a;
        objData4->a = b;
        ret += objData3->a;
        ret += objData4->a;

        ((ObjectType*)(_objData1))->a = a;
        ((ObjectType*)(_objData2))->a = b;
        ret += ((ObjectType*)(_objData1))->a;
        ret += ((ObjectType*)(_objData2))->a;


        return ret;
    }