综合技术
直播中

夏涌革

7年用户 170经验值
私信 关注
[问答]

请问一个函数的返回值能是任意值吗?

在USMART(一个串口调试互交组建)的设计过程中,需要一个通用的函数原型,来匹配各种函数(不包含指针参量,即参数和返回值都不为指针类型).以达到函数受usmart管理的目的.
下面是核心定义:

//定义一个通用的函数类型
//usmart_func的返回值为u32,参数待定.
typedef u32(*usmart_func)();//定义函数类型
//函数名列表  
struct _m_usmart_nametab
{
usmart_func func;  //函数指针
const u8* name;  //函数名(查找串)  
};
//usmart控制管理器
struct _m_usmart_dev
{
struct _m_usmart_nametab *funs; //函数名指针
void (*init)(void);    //初始化
u8 (*cmd_rec)(u8*str);   //识别函数名及参数
void (*exe)(void);     //执行
void (*scan)(void);             //扫描
u8 fnum;         //函数数量
u8 pnum;                        //参数数量
u8 id;       //函数id
u32 pARM[MAX_PARM];           //函数的参数(最大参数)
};
extern struct _m_usmart_nametab usmart_nametab[]; //在usmart_config.c里面定义
extern struct _m_usmart_dev usmart_dev;    //在usmart_config.c里面定义

上面,我把通用的函数原型定义为u32的返回类型,以适应最大返回值的情况.但是这样的定义,在函数返回值为void或者u8,u16的时候,会产生警告.不知道有没有办法让函数原型可以返回任意值,而不产生警告呢?
在另外一个.c文件里面,通过如下方法初始化函数名列表:
//函数名列表初始化(用户自己添加)
//用户直接在这里输入要执行的函数名及其查找串
struct _m_usmart_nametab usmart_nametab[]=
{
delay_ms,"delay_ms",
delay_us,"delay_us",
SPI_Flash_ReadID,"SPI_Flash_ReadID",
Seg_Show_Num,"Seg_Show_Num",
Seg_Show_Char,"Seg_Show_Char",
RTC_Set,"RTC_Set",
Seg_Clear,"Seg_Clear",
Seg_Show_Str,"Seg_Show_Str",
EXIO_Set,"EXIO_Set",
EXIO_Scan,"EXIO_Scan",
Seg_Dot_Set,"Seg_Dot_Set",
ATR_TEST,"ATR_TEST",
Test_Read,"Test_Read",
MRAM_Read,"MRAM_Read",
RAM_Read,"PRAM_Read",
Start_Transaction,"Start_Transaction",
TEST_RD_REC,"TEST_RD_REC",
TEST_WR_REC,"TEST_WR_REC",
Sle_WR_Cmd,"Sle_WR_Cmd",
Flash_Get_Recnum,"Flash_Get_Recnum",
    SPI_Flash_Erase_Chip,"SPI_Flash_Erase_Chip",
TEST_WR_ALL,"TEST_WR_ALL",
Test_Write,"Test_Write",  
TEST_Ver,"TEST_Ver",  
  
};
以上各个函数,有的返回void,有的返回u8有的返回u16.导致很多警告.希望高人指点一下,如何能去掉这些警告?
下面是编译后的警告:



图片不清晰,看下面的:
..USMARTusmart_config.c(22): warning:  #144-D: a value of type "void (*)(u16)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(23): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(24): warning:  #144-D: a value of type "u16 (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(25): warning:  #144-D: a value of type "void (*)(u8, u32, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(26): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(27): warning:  #144-D: a value of type "u8 (*)(u16, u8, u8, u8, u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(28): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(29): warning:  #144-D: a value of type "void (*)(u8, u8 *)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(30): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(31): warning:  #144-D: a value of type "u8 (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(32): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(33): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(34): warning:  #144-D: a value of type "u8 (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(35): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(36): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(37): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(38): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(39): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(40): warning:  #144-D: a value of type "void (*)(u8, u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(42): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(43): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(44): warning:  #144-D: a value of type "u8 (*)(u8, u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..USMARTusmart_config.c(45): warning:  #144-D: a value of type "u8 (*)(u8, u8, u8)" cannot be used to initialize an entity of type "usmart_func"

回帖(8)

俞敏东

2019-10-8 08:14:32



  • #include

  • #include



  • struct _m_usmart_nametab

  • {

  •     void * func;  //函数指针

  •     char * name;  //函数名(查找串)

  • };



  • void test1(void)

  • {

  •     printf("fun test1 done!rn");

  •     return;

  • }



  • int test2(void)

  • {

  •     printf("fun test2 done!rn");

  •     return 2;

  • }



  • int test3(int arg)

  • {

  •     printf("arg is :%drn",arg);

  •     printf("fun test3 done!rn");

  •     return arg*2;

  • }



  • unsigned long test4(int arg1,unsigned long arg2)

  • {

  •     printf("arg1 is :%drn",arg1);

  •     printf("arg2 is :0x%Xrn",arg2);

  •     printf("fun test4 done!rn");

  •     return arg2+1;

  • }



  • struct _m_usmart_nametab usmart_nametab[]=

  • {

  •     {test1,"void test1(void)",},

  •     {test2,"int test2(void)",},

  •     {test3,"int test3(int arg)",},

  •     {test4,"unsigned long test4(int arg1,unsigned long arg2)",},

  • };



  • int main()

  • {

  •     unsigned long return_value = 0;

  •     unsigned int return_long = 0;



  •     // 函数类型 (*指针变量名)(形参列表);



  •     printf("function name: %srn",usmart_nametab[0].name);

  •     test1();

  •     printf("***rnfunction table:rn");

  •     return_value = (*(unsigned long(*)())usmart_nametab[0].func)();

  •     printf("return_value is : %drn",return_value);



  •     printf("rnfunction name: %srn",usmart_nametab[1].name);

  •     printf("return_value is : %drn",test2());

  •     printf("***rnfunction table:rn");

  •     return_value = (*(int(*)())usmart_nametab[1].func)();

  •     printf("return_value is : %drn",return_value);



  •     printf("rnfunction name: %srn",usmart_nametab[2].name);

  •     printf("return_value is : %drn",test3(4));

  •     printf("***rnfunction table:rn");

  •     return_value = (*(int(*)(int))usmart_nametab[2].func)(5);

  •     printf("return_value is : %drn",return_value);



  •     printf("rnfunction name: %srn",usmart_nametab[3].name);

  •     printf("return_value is : %Xrn",test4(4,0xFFFFFFF7));

  •     printf("***rnfunction table:rn");

  •     return_long = (*(unsigned long(*)(int,unsigned long))usmart_nametab[3].func)(5,0xFFFFFFF8);

  •     printf("return_long is : %Xrn",return_long);



  •     return 0;

  • }

复制代码
举报

赵护林

2019-10-8 08:20:38
谢谢.后来给我的代码可用.
struct _m_usmart_nametab
{
    void * func;  //函数指针
    char * name;  //函数名(查找串)
};
void test1(void)
{
    printf("fun test1 done!rn");
    return;
}
int test2(void)
{
    printf("fun test2 done!rn");
    return 2;
}
int test3(int arg)
{
    printf("arg is:%drn",arg);
    printf("fun test3 done!rn");
    return arg*2;
}
unsigned long test4(int arg1,unsigned long arg2)
{
    printf("arg1 is:%drn",arg1);
    printf("arg2 is:0x%Xrn",arg2);
    printf("fun test4 done!rn");
    return arg2+1;
}
struct _m_usmart_nametab usmart_nametab[]=
{
    {(void*)test1,"void test1(void)",},
    {(void*)test2,"int test2(void)",},
    {(void*)test3,"int test3(int arg)",},
    {(void*)test4,"unsigned long test4(int arg1,unsigned long arg2)",},
};
int main(void)
{
    //启用PLL运行在72M
//    SystemInit();
     printf("hello");
    // 测试
    {
        unsigned long return_value = 0;
        unsigned int return_long = 0;
        // 函数类型 (*指针变量名)(形参列表);
        printf("function name: %srn",usmart_nametab[0].name);
        test1();
        printf("***rnfunction table:rn");
        return_value = (*(unsigned long(*)())usmart_nametab[0].func)();
        printf("return_value is: %drn",return_value);
        printf("rnfunction name: %srn",usmart_nametab[1].name);
        printf("return_value is: %drn",test2());
        printf("***rnfunction table:rn");
        return_value = (*(int(*)())usmart_nametab[1].func)();
        printf("return_value is: %drn",return_value);
        printf("rnfunction name: %srn",usmart_nametab[2].name);
        printf("return_value is: %drn",test3(4));
        printf("***rnfunction table:rn");
        return_value = (*(int(*)(int))usmart_nametab[2].func)(5);
        printf("return_value is: %drn",return_value);
        printf("rnfunction name: %srn",usmart_nametab[3].name);
        printf("return_value is: %Xrn",test4(4,0xFFFFFFF7));
        printf("***rnfunction table:rn");
        return_long = (*(unsigned long(*)(int,unsigned long))usmart_nametab[3].func)(5,0xFFFFFFF8);
        printf("return_long is: %Xrn",return_long);
    }
    // 测试
 }
举报

张丽

2019-10-8 08:31:37
在aozima的帮助下,过几天我会公布USMARTV1.4的源码.
V1.4的主要新特性:
1,支持字符串参数.
2,优化参数存储方式,内存占用显著减小.
3,自适应参数长度(连函数名,总数不超过64个字节.ps:只需要自行修改usart.c的部分内容,即可支持大于64字节.)
4,去掉了警告(在aozima帮助下解决,特此感谢!).
举报

曹光辉

2019-10-8 08:41:57
一般 函数类型不一样的时候 , 都用 void * 指针传递 , 最后强制转换成某种类型
举报

更多回帖

发帖
×
20
完善资料,
赚取积分