visualfc

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  42 随笔 :: 0 文章 :: 119 评论 :: 0 Trackbacks
    本文编写 visualfc

    写一个invoke函数以支持任意参数调用,实现类似以下的功能代码。注:本代码纯属试验。
  1. class a
  2. {
  3.    void func1(int,int);
  4.    void func2(char*,int);
  5. };

  6. void invoke(a*,char * method,...);

  7. void test()
  8. {
  9.    a a1,
  10.    invoke(&a1,"func1",10,20);
  11.    invoke(&a2,"func2","ok",0);
  12. }
    我目前试验了三种方式,第一种是模板方式实现,第二种是基于可变参数(...)实现,第三种是使用类似boost::any的方式来实现。比较三种方式, 模板方式实现起来尤其不易,但是能够做参数检查,问题在于只能存在在头文件中。 第二种为可变参数方式, 本文给出了这种方式的试验代码,实现起来也比较简单,问题是无法验证参数。第三种方式为以类似any的方式来实现,但是实现效率则相对较低。
    下面给出了第二种方式,即使用可变参数调用的实现,没有使用va_list和va_arg,这是因为函数调用栈顺序的原因,我使用了自定义的get_arg_back函数来获取可变参数。

  1. template <typename T>
  2. T get_arg_back(char ** parg)
  3. {
  4.     *parg -= sizeof(T);
  5.     T t = *((T*)*parg);
  6.     return t;
  7. }
  8. template <typename R, typename CLS, typename T1, typename T2>
  9. R invoke_cls(CLS * pcls, R (CLS::*ptr)(T1,T2), char ** parg)
  10. {
  11.     char * end = *parg+sizeof(T1)+sizeof(T2);
  12.     return (pcls->*ptr)(get_arg_back<T1>(&end),get_arg_back<T2>(&end));
  13. }

  14. class a
  15. {
  16. public:
  17.     int test(char * buf, int i)
  18.     {
  19.         printf ("test %s %d\n",buf,i);
  20.         return 0;
  21.     }
  22.     int test2(int i, char * buf)
  23.     {
  24.         printf ("test2 %s %d\n",buf,i);
  25.         return 100;
  26.     }
  27. };
  28. void invoke(void * ptr, char * method,...)
  29. {
  30.     char * parg = (char*)&method+sizeof(method);
  31.     if (method == "test")
  32.         invoke_cls((a*)ptr,&a::test,&parg);
  33.     else if (method == "test2")
  34.         invoke_cls((a*)ptr,&a::test2,&parg);
  35.     parg = NULL;
  36. }
  37. int main(int argc, char* argv[])
  38. {
  39.     a a1;
  40.     invoke(&a1,"test","ok",1);
  41.     invoke(&a1,"test2",1,"ok");
  42.     return 0;
  43. }


posted on 2008-10-11 16:37 visualfc 阅读(1626) 评论(1)  编辑 收藏 引用 所属分类: C++

评论

# re: 关于可变参数函数调用 2008-10-11 18:14 陈梓瀚(vczh)
boost的Functor的代码展开之后,如果你要求产生最多20个参数的函数对象的话,那么他就将有20个互相之间没有关系的类。

第二种做法是,将参数声明写进宏,虽然要重复一次数据,但是只需要一个类就可以了。

第三种做法,目前没有。  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理