我想确保一组函数在某些C代码中具有相同的签名。理想情况下,我将能够定义一个描述函数的返回值和参数的新类型,然后使用这个新类型声明我的一组函数。如何在C中的一组函数声明上强制执行函数签名?
此外,有没有一种方法来指定该函数typedef的参数的默认值?
我想确保一组函数在某些C代码中具有相同的签名。理想情况下,我将能够定义一个描述函数的返回值和参数的新类型,然后使用这个新类型声明我的一组函数。如何在C中的一组函数声明上强制执行函数签名?
此外,有没有一种方法来指定该函数typedef的参数的默认值?
/* define a typedef for function_t - functions that return void */
/* and take an int and char parameter */
typedef void function_t(int param1, char param2);
/* declare some functions that use that signature */
function_t foo;
function_t bar;
现在,当您定义函数时,如果它们不使用与typedef中相同的签名,将会出现错误。
void foo(int x, char c)
{
/* do some stuff */
return;
}
/* this will result in a compiler error */
int bar(int x, char c)
{
/* do some stuff */
return 1;
}
至于你的新问题(添加零八年十月二十零日):“另外,有没有为传递到该函数的typedef指定默认值的方法吗?”
不,没有办法将默认参数添加到typedef。当然不是在C中,它根本不支持默认参数。即使在C++中,也不能这样做,因为参数的默认值不是该类型的一部分。实际上,从基类中覆盖虚拟方法的类可以为默认参数指定不同的值(或者甚至完全删除默认参数) - 但是,这是不应该一般地完成的,因为它只会导致混淆(http://www.gotw.ca/gotw/005.htm)。
如果您正在使用C++,你也许能得到您想要使用的一个行为(或组合)以下:
但它会很难提出好的建议,而无需了解EXAC更多的细节真正想要完成的是什么。而且我认为结果很可能相当不好。
这类似于一个函数指针是如何工作的:
// Declaration of function with int arg returning int
typedef int (*CALLBACK)(int);
//Definition
int myFunc(int arg)
{
return 0;
}
// Function pointer usage
CALLBACK pFunc = myFunc;
我不认为你可以直接做到这一点,但你可以定义一个函数指针类型,然后收集所有功能集成到一个数组。编译器会让你知道哪些不匹配。
typedef void (*MethodSig)(int, int);
static MethodSig x[] = { fnA, fnB, ... };
或者使用宏来声明函数签名
#define MyFunc(X) void X(int a, int b)
这样,他们都将是相同的。
你不能真正阻止任何人使一个函数有任何签名。但是你可以控制你要打的电话。所以我认为这是你想要的。
有将调用任意函数的函数以函数的指针作为参数。既然你提到的typedef,您可以在程序中早期定义的类型定义,像这样:
假设你只想要签名“无符号短id_for_allowed_functions(INT X,字符* Y)”的功能:
typedef unsigned short (*id_for_allowed_functions)(int, char*);
然后,您的通话功能:
void calling_function (id_for_allowed_function x) { (*x)(3, "bla"); }
并且提供函数foo它:
unsigned short foo(int x, char* y) { /* ... */ }
calling_function(&foo);
下面是创建映射到简单字符串的函数列表的示例。
首先是类型定义:
typedef GenList *(*DBLISTLOADER)(Database *pDB, char *quellCD, char *profilName);
typedef ObjDescription *(*DBCOLUMNLOADER)();
typedef struct dbinfo
{
char *dbName;
DBLISTLOADER dbListLoader;
DBCOLUMNLOADER dbColumnLoader;
char *options;
} DBINFO;
则映射表:
DBINFO dbInfoList[] =
{
{ "SRCDOC", loadSRCDOC, colSRCDOC, "q" },
{ "PRF_CD", loadPRF_CD, colPRF_CD, "" },
{ "MEDIA", loadMEDIA, colMEDIA, "" },
{ NULL, NULL, NULL }
};
我们从该表中查找一个函数并调用它:
while (dbInfoList[i].dbName != NULL)
{
if (strcmp(dbInfoList[i].dbName, szDatabase) == 0)
{
return (dbInfoList[i].dbListLoader)(pDB, quellCD, profilName);
}
i++;
}
很抱歉,如果它是一个有点'生'。直接从我们的代码粘贴;-)
哇,我从来没有那样,只是作为函数指针。你可以重用函数定义的function_t吗? – quinmars 2008-10-09 18:30:33