OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13091|回复: 9

可否让一个函数的返回值可以是任意值呢?(USMART设计中遇到的问题)

[复制链接]

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
发表于 2011-4-28 14:23:22 | 显示全部楼层 |阅读模式

 在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.导致很多警告.希望高人指点一下,如何能去掉这些警告?
下面是编译后的警告:


图片不清晰,看下面的:
..\USMART\usmart_config.c(22): warning:  #144-D: a value of type "void (*)(u16)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(23): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(24): warning:  #144-D: a value of type "u16 (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_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"
..\USMART\usmart_config.c(26): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_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"
..\USMART\usmart_config.c(28): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(29): warning:  #144-D: a value of type "void (*)(u8, u8 *)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(30): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(31): warning:  #144-D: a value of type "u8 (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(32): warning:  #144-D: a value of type "void (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(33): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(34): warning:  #144-D: a value of type "u8 (*)(u8, u8)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(35): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(36): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(37): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(38): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(39): warning:  #144-D: a value of type "void (*)(u32)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_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"
..\USMART\usmart_config.c(42): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_config.c(43): warning:  #144-D: a value of type "void (*)(void)" cannot be used to initialize an entity of type "usmart_func"
..\USMART\usmart_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"
..\USMART\usmart_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"


 

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
 楼主| 发表于 2011-4-28 14:29:01 | 显示全部楼层
在百度上搜到,有人说可以用联合体,但是我试过,警告依旧.(测试软件是MDK3.80A).
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3713
金钱
3713
注册时间
2011-5-23
在线时间
2011 小时
发表于 2011-5-23 22:14:58 | 显示全部楼层
  1. <br />
  2. #include &lt;stdio.h&gt;<br />
  3. #include &lt;stdlib.h&gt;<br />
  4. <br />
  5. struct _m_usmart_nametab<br />
  6. {<br />
  7. &nbsp;&nbsp;&nbsp; void * func;&nbsp; //函数指针<br />
  8. &nbsp;&nbsp;&nbsp; char * name;&nbsp; //函数名(查找串)<br />
  9. };<br />
  10. <br />
  11. void test1(void)<br />
  12. {<br />
  13. &nbsp;&nbsp;&nbsp; printf("fun test1 done!\r\n");<br />
  14. &nbsp;&nbsp;&nbsp; return;<br />
  15. }<br />
  16. <br />
  17. int test2(void)<br />
  18. {<br />
  19. &nbsp;&nbsp;&nbsp; printf("fun test2 done!\r\n");<br />
  20. &nbsp;&nbsp;&nbsp; return 2;<br />
  21. }<br />
  22. <br />
  23. int test3(int arg)<br />
  24. {<br />
  25. &nbsp;&nbsp;&nbsp; printf("arg is :%d\r\n",arg);<br />
  26. &nbsp;&nbsp;&nbsp; printf("fun test3 done!\r\n");<br />
  27. &nbsp;&nbsp;&nbsp; return arg*2;<br />
  28. }<br />
  29. <br />
  30. unsigned long test4(int arg1,unsigned long arg2)<br />
  31. {<br />
  32. &nbsp;&nbsp;&nbsp; printf("arg1 is :%d\r\n",arg1);<br />
  33. &nbsp;&nbsp;&nbsp; printf("arg2 is :0x%X\r\n",arg2);<br />
  34. &nbsp;&nbsp;&nbsp; printf("fun test4 done!\r\n");<br />
  35. &nbsp;&nbsp;&nbsp; return arg2+1;<br />
  36. }<br />
  37. <br />
  38. struct _m_usmart_nametab usmart_nametab[]=<br />
  39. {<br />
  40. &nbsp;&nbsp;&nbsp; {test1,"void test1(void)",},<br />
  41. &nbsp;&nbsp;&nbsp; {test2,"int test2(void)",},<br />
  42. &nbsp;&nbsp;&nbsp; {test3,"int test3(int arg)",},<br />
  43. &nbsp;&nbsp;&nbsp; {test4,"unsigned long test4(int arg1,unsigned long arg2)",},<br />
  44. };<br />
  45. <br />
  46. int main()<br />
  47. {<br />
  48. &nbsp;&nbsp;&nbsp; unsigned long return_value = 0;<br />
  49. &nbsp;&nbsp;&nbsp; unsigned int return_long = 0;<br />
  50. <br />
  51. &nbsp;&nbsp;&nbsp; // 函数类型 (*指针变量名)(形参列表);<br />
  52. <br />
  53. &nbsp;&nbsp;&nbsp; printf("function name: %s\r\n",usmart_nametab[0].name);<br />
  54. &nbsp;&nbsp;&nbsp; test1();<br />
  55. &nbsp;&nbsp;&nbsp; printf("***\r\nfunction table:\r\n");<br />
  56. &nbsp;&nbsp;&nbsp; return_value = (*(unsigned long(*)())usmart_nametab[0].func)();<br />
  57. &nbsp;&nbsp;&nbsp; printf("return_value is : %d\r\n",return_value);<br />
  58. <br />
  59. &nbsp;&nbsp;&nbsp; printf("\r\nfunction name: %s\r\n",usmart_nametab[1].name);<br />
  60. &nbsp;&nbsp;&nbsp; printf("return_value is : %d\r\n",test2());<br />
  61. &nbsp;&nbsp;&nbsp; printf("***\r\nfunction table:\r\n");<br />
  62. &nbsp;&nbsp;&nbsp; return_value = (*(int(*)())usmart_nametab[1].func)();<br />
  63. &nbsp;&nbsp;&nbsp; printf("return_value is : %d\r\n",return_value);<br />
  64. <br />
  65. &nbsp;&nbsp;&nbsp; printf("\r\nfunction name: %s\r\n",usmart_nametab[2].name);<br />
  66. &nbsp;&nbsp;&nbsp; printf("return_value is : %d\r\n",test3(4));<br />
  67. &nbsp;&nbsp;&nbsp; printf("***\r\nfunction table:\r\n");<br />
  68. &nbsp;&nbsp;&nbsp; return_value = (*(int(*)(int))usmart_nametab[2].func)(5);<br />
  69. &nbsp;&nbsp;&nbsp; printf("return_value is : %d\r\n",return_value);<br />
  70. <br />
  71. &nbsp;&nbsp;&nbsp; printf("\r\nfunction name: %s\r\n",usmart_nametab[3].name);<br />
  72. &nbsp;&nbsp;&nbsp; printf("return_value is : %X\r\n",test4(4,0xFFFFFFF7));<br />
  73. &nbsp;&nbsp;&nbsp; printf("***\r\nfunction table:\r\n");<br />
  74. &nbsp;&nbsp;&nbsp; return_long = (*(unsigned long(*)(int,unsigned long))usmart_nametab[3].func)(5,0xFFFFFFF8);<br />
  75. &nbsp;&nbsp;&nbsp; printf("return_long is : %X\r\n",return_long);<br />
  76. <br />
  77. &nbsp;&nbsp;&nbsp; return 0;<br />
  78. }<br />
复制代码


RT-Thread RTOS 音频,WIFI,蓝牙
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
 楼主| 发表于 2011-5-23 23:07:13 | 显示全部楼层
回复【3楼】aozima:
---------------------------------
谢谢.后来给我的代码可用.
struct _m_usmart_nametab
{
    void * func;  //函数指针
    char * name;  //函数名(查找串)
};

void test1(void)
{
    printf("fun test1 done!\r\n");
    return;
}

int test2(void)
{
    printf("fun test2 done!\r\n");
    return 2;
}

int test3(int arg)
{
    printf("arg is:%d\r\n",arg);
    printf("fun test3 done!\r\n");
    return arg*2;
}

unsigned long test4(int arg1,unsigned long arg2)
{
    printf("arg1 is:%d\r\n",arg1);
    printf("arg2 is:0x%X\r\n",arg2);
    printf("fun test4 done!\r\n");
    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: %s\r\n",usmart_nametab[0].name);
        test1();
        printf("***\r\nfunction table:\r\n");
        return_value = (*(unsigned long(*)())usmart_nametab[0].func)();
        printf("return_value is: %d\r\n",return_value);

        printf("\r\nfunction name: %s\r\n",usmart_nametab[1].name);
        printf("return_value is: %d\r\n",test2());
        printf("***\r\nfunction table:\r\n");
        return_value = (*(int(*)())usmart_nametab[1].func)();
        printf("return_value is: %d\r\n",return_value);

        printf("\r\nfunction name: %s\r\n",usmart_nametab[2].name);
        printf("return_value is: %d\r\n",test3(4));
        printf("***\r\nfunction table:\r\n");
        return_value = (*(int(*)(int))usmart_nametab[2].func)(5);
        printf("return_value is: %d\r\n",return_value);

        printf("\r\nfunction name: %s\r\n",usmart_nametab[3].name);
        printf("return_value is: %X\r\n",test4(4,0xFFFFFFF7));
        printf("***\r\nfunction table:\r\n");
        return_long = (*(unsigned long(*)(int,unsigned long))usmart_nametab[3].func)(5,0xFFFFFFF8);
        printf("return_long is: %X\r\n",return_long);
    }
    // 测试
 }
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
 楼主| 发表于 2011-5-23 23:10:26 | 显示全部楼层
在aozima的帮助下,过几天我会公布USMARTV1.4的源码.
V1.4的主要新特性:
1,支持字符串参数.
2,优化参数存储方式,内存占用显著减小.
3,自适应参数长度(连函数名,总数不超过64个字节.ps:只需要自行修改usart.c的部分内容,即可支持大于64字节.)
4,去掉了警告(在aozima帮助下解决,特此感谢!).
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

1263

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1612
金钱
1612
注册时间
2012-6-15
在线时间
39 小时
发表于 2013-2-5 10:33:01 | 显示全部楼层
一般 函数类型不一样的时候 , 都用 void * 指针传递 , 最后强制转换成某种类型
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2013-3-24
在线时间
1 小时
发表于 2013-7-17 23:14:39 | 显示全部楼层
弱弱的问一句:“void * func;  //函数指针 ”注释是否有误?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
 楼主| 发表于 2013-7-18 11:11:48 | 显示全部楼层
回复【7楼】liuyinggui163:
---------------------------------
没有啊,确实是用来指向函数的指针.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

26

主题

101

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2013-8-1
在线时间
57 小时
发表于 2014-5-16 17:14:35 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
不是应该是void (* func)(void)后面的括号可以省略?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
 楼主| 发表于 2014-5-16 20:00:22 | 显示全部楼层
回复【9楼】zyjs1987:
---------------------------------
你试试
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-5 13:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表