如何获得函数的参数信息,包括参数类型和参数个数?

bugebear3 2005-10-28 09:14:40
如何获得函数的参数信息,包括参数类型和参数个数?是否要使用变参函数的Va_List之类的东西?
...全文
737 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
bugebear3 2005-10-28
  • 打赏
  • 举报
回复
由于工作需要,我要设计一个脚本语言(象Lua一样),但由于Lua是一种通用的脚本语言,效率较低,并且也无法调用C++的东西,因此项目需要我们自己设计一种脚本语言.
目前,老大已经在VC下实现了全部功能(方法是用内嵌汇编),我的任务是将其移植到GCC下去,由于GCC下对参数和函数调用的处理与VC下不同,因此我需要找到一种机制,来获取函数参数类型和个数,其实最终想获得参数所占的空间大小,然后根据GCC16字节对齐的情况,在所有参数入栈之前,执行一条语句:__asm__ volatile("subl SIZE %esp \n\t "),这里的SIZE是由函数参数的类型和个数决定的,只有这样,才能保证内存16字节对齐,也才能保证参数出栈时不会出现混乱的情况,否则会出现core dump.
megaboy 2005-10-28
  • 打赏
  • 举报
回复
在C里面,这个问题是做不到的。即使用可变参数也不行。

可变参数利用第一个参数来计算后续参数的偏移量,但类型得根据格式字符串的说明,写出格式字符串就已经是人为地规定了参数的类型了,不是真正意义上的运行时。
sisn 2005-10-28
  • 打赏
  • 举报
回复
看看 va_list ,va_arg, va_begin, va_end 的定义....

程序自动判断参数是什么类型是更不不可能的..

你怎么知道栈里参数 是一个 数值 还是指向某个内存的指针?
只能有调用者自己指定!!

va_list 之类的定义我都研究过..
至于其它相关资料. 我不知道,如有请各位赐教:)

漂流的代码 2005-10-28
  • 打赏
  • 举报
回复
不知道楼主是一时兴趣还是的确遇到这样的难题.
我认为,这个恐怕不可能.
从编译的结果看,参数的传递只是约定.这里有两个问题,
1是参数的顺序,有从左到右和从右到左
2是参数的类型.
事实上,参数的类型有两个含义,一个是参数占用了多大的空间,另外是参数值的含义是什么
在汇编层次,这两方面都是约定的,没有任何信息,除非你自己添加代码支持

从语言层次上,C/C++都没有提供任何的控制来取得这些信息.
从变参数典型应用printf函数看,就是这样
printf函数只要有一个参数,就是format参数,这个参数有两个作用,
1.提供一个输出模板,
2.描述可选参数的数目和类型
例如printf("%s,%d",str,interger);
%s 表示一个const char*类型
%d 表示一个int类型
这里一共有两个变参数.
varargs.h这样定义 va_list
#ifdef _M_ALPHA
typedef struct {
char *a0; /* pointer to first homed integer argument */
int offset; /* byte offset of next parameter */
} va_list;
#else
typedef char *va_list;
#endif
char* a0表示变参数实际上是一段长度不确定的内存
#define va_start(ap) ap = (va_list)&va_alist
icecools(浮生若梦)给出的例子va_start(first)说明,第一个参数是变参数的开始地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
va_arg其实就是偏移量,但是究竟应该偏移多少是不确定的
#define va_end(ap) ap = (va_list)0
va_end说明这个变参列表由编译器自动管理

我不太清楚楼主的真实想法:
是在一个函数内部,如何获得别人传给他的参数序列
还是说,在函数外部静态的获取函数的参数信息.
第一种情况,只能有变参数,而且你的第一个参数必须包含了变参的格式或者个数信息
第二种情况是不可能实现的
icecools 2005-10-28
  • 打赏
  • 举报
回复
example from MSDN:
#include <stdio.h>
#define ANSI /* Comment out for UNIX version */
#ifdef ANSI /* ANSI compatible version */
#include <stdarg.h>
int average( int first, ... );
#else /* UNIX compatible version */
#include <varargs.h>
int average( va_list );
#endif

int main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}

/* Returns the average of a variable list of integers. */
#ifdef ANSI /* ANSI compatible version */
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
#else /* UNIX compatible version must use old-style definition. */
int average( va_alist )
va_dcl
{
int i, count, sum;
va_list marker;

va_start( marker ); /* Initialize variable arguments. */
for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
sum += i;
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
#endif
luoknd 2005-10-28
  • 打赏
  • 举报
回复
有点难度???高手说说
majinyi 2005-10-28
  • 打赏
  • 举报
回复
记得在C++编程思想的第一章还是第二章的练习题你有一个你要问的问题
你说用可变参数求是可以的,在网上找点有关可变参数的资料看看很容易实现
lifengice0706 2005-10-28
  • 打赏
  • 举报
回复
又是这个有挑战性的问题,gz

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧