LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2467|回复: 11

请教typedef void

[复制链接]
发表于 2008-10-7 21:16:50 | 显示全部楼层 |阅读模式

  1. typedef void (*RtpTimerFunc)(void)

  2. struct _RtpTimer
  3. {
  4.   int state;
  5.   RtpTimerFunc timer_init;
  6.   RtpTimerFunc timer_do;
  7.   RtpTimerFunc timer_uninit;
  8.   struct timeval interval;
  9. }
复制代码


这是oRTP中的一段源码。
我有几个问题,请大家赐教。
1.这里typedef void的用法能否解释一下。
2.什么时候采取这种用法?
3.这种用法的好处?
谢谢!
发表于 2008-10-7 21:56:27 | 显示全部楼层
你把 (*xxx) 换成 xxx 就看明白了:

void xxx(void)

一看,这原来就是定义一个函数。

(*xxx)形式就是一个函数指针。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-8 13:34:51 | 显示全部楼层

  1. #if defined(WIN32) || defined(_WIN32_WCE)
  2. #include "ortp-config-win32.h"
  3. #else
  4. #include "ortp-config.h"
  5. #endif

  6. #include "ortp/ortp.h"
  7. #include "rtptimer.h"

  8. #if        !defined(_WIN32) && !defined(_WIN32_WCE)

  9. #ifdef __linux__
  10. #include <sys/select.h>
  11. #endif
  12. #include <sys/time.h>
  13. #include <sys/types.h>
  14. #include <unistd.h>


  15. static struct timeval orig,cur;
  16. static uint32_t posix_timer_time=0;                /*in milisecond */

  17. void posix_timer_init()
  18. {
  19.         posix_timer.state=RTP_TIMER_RUNNING;
  20.         gettimeofday(&orig,NULL);
  21.         posix_timer_time=0;
  22. }


  23. void posix_timer_do()
  24. {
  25.         int diff,time;
  26.         struct timeval tv;
  27.         gettimeofday(&cur,NULL);
  28.         time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
  29.         if ( (diff=time-posix_timer_time)>50){
  30.                 ortp_warning("Must catchup %i miliseconds.",diff);
  31.         }
  32.         while((diff = posix_timer_time-time) > 0)
  33.         {
  34.                 tv.tv_sec = diff/1000;
  35.                 tv.tv_usec = (diff%1000)*1000;
  36. #if        defined(_WIN32) || defined(_WIN32_WCE)
  37.         /* this kind of select is not supported on windows */
  38.                 Sleep(tv.tv_usec/1000 + tv.tv_sec * 1000);
  39. #else
  40.                 select(0,NULL,NULL,NULL,&tv);
  41. #endif
  42.                 gettimeofday(&cur,NULL);
  43.                 time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
  44.         }
  45.         posix_timer_time+=POSIXTIMER_INTERVAL/1000;
  46.        
  47. }

  48. void posix_timer_uninit()
  49. {
  50.         posix_timer.state=RTP_TIMER_STOPPED;
  51. }

  52. RtpTimer posix_timer={        0,
  53.                                                 posix_timer_init,
  54.                                                 posix_timer_do,
  55.                                                 posix_timer_uninit,
  56.                                                 {0,POSIXTIMER_INTERVAL}};
  57.                                                        
复制代码


谢谢楼上的指教。
上面是oRTP中的posixtimer.c(去掉了win32部分)。为了便于说明问题,我只好贴这么长,不好意思。
我的疑问是,在声明RtpTimer posix_timer这个变量的时候,它会自动地把posix_timer_init, posix_timer_do,和posix_timer_uninit三个函数执行一遍吗?
如果不是,那么怎么把这三个函数用起来,怎么来执行它们?
是这样写吗:posix_timer.posix_timer_init

我仿造了个例子如下

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef void (* FUNC)(void);

  4. typedef struct _mystruct  
  5. {
  6.         int item;
  7.         FUNC AnyWords;
  8. } MyStruct;


  9. void SetItem()
  10. {
  11.         test.item = 10;
  12. }

  13. MyStruct test = {0, SetItem};

  14. int main()
  15. {
  16.         printf("--- test start ---\n");
  17.         printf(" item is %d\n", test.item);
  18.         exit(0);
  19. }
复制代码


上面有错误,在void SetItem里,test是未声明的变量.
但是我把MyStruct test声明在void SetItem()前面的话,SetItem又变成未声明。
真奇怪,源码是如何做到的呢?
回复 支持 反对

使用道具 举报

发表于 2008-10-8 15:31:53 | 显示全部楼层
楼主要好好补习一下c语言了
你的代码缺少函数声明,所以把MyStruct test放前面就SetItem变成未声明
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-8 20:14:33 | 显示全部楼层
是的,基本功不扎实。。。
但是我想问的却不是在这个地方,有时候自己的话语表达不清晰,加上贴的例子有语法错误,大家的注意力都被吸引过去了。。。
晚上问了师兄,已经搞清楚了,谢谢楼上两位的提醒,typedef和声明,这下不会再犯晕了。
我贴一下整理后的例子,用c语言来模拟c++的一些特性。


  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef void (* FUNC)(void);

  4. typedef struct _mystruct  
  5. {
  6.         int item;
  7.         FUNC AnyWords;
  8. } MyStruct;

  9. extern MyStruct test;

  10. //以上一般包含在头文件中

  11. int item = 0;

  12. void SetItem()
  13. {
  14.         test.item = 10;
  15. }

  16. MyStruct test = {0, SetItem};

  17. int main()
  18. {
  19.         MyStruct *ptr;
  20.         ptr = &test;
  21.         printf("--- test start ---\n");
  22.         ptr->AnyWords();
  23.         printf(" item is %d \n", ptr->item);
  24.         exit(0);
  25. }

  26. //这种用法实际上是用c语言来实现c++的一些特性,FUNC AnyWords相当于成员函数。
  27. //成员函数的具体实现可以各自定义实现,但是使用的时候用到的是统一的接口ptr->AnyWords(),而不是ptr->SetItem()
复制代码
回复 支持 反对

使用道具 举报

发表于 2008-10-9 16:26:57 | 显示全部楼层
按这顺序就可以了,用不着什么extern定义

void SetItem();

MyStruct test = {0, SetItem};

void SetItem()
{
        test.item = 10;
}
回复 支持 反对

使用道具 举报

发表于 2008-10-13 11:42:05 | 显示全部楼层
呵呵,里面extern的用法的确有些奇怪
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-14 15:23:02 | 显示全部楼层
Post by hanchao3c;1893402
呵呵,里面extern的用法的确有些奇怪


单独从这个简短的例子来看是比较奇怪,但是从一个大的工程来看就不奇怪了。
而且在头文件中显示定义extern没有错吧。
回复 支持 反对

使用道具 举报

发表于 2008-10-26 21:30:55 | 显示全部楼层
LZ 说的貌似函数指针
回复 支持 反对

使用道具 举报

发表于 2008-10-27 17:42:24 | 显示全部楼层
Post by motive;1893888
单独从这个简短的例子来看是比较奇怪,但是从一个大的工程来看就不奇怪了。
而且在头文件中显示定义extern没有错吧。


没有错,但是你写的不是头文件。

还可以把用一个宏代替extern,这样自己用的是没有extern的,头文件别人用的是有extern的
回复 支持 反对

使用道具 举报

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

本版积分规则

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