我一直在浏览Atmel库的USB for AT91SAM7,有些东西我不明白。端点是一个定义如下的结构:
typedef struct {
volatile unsigned char state;
volatile unsigned char bank;
volatile unsigned short size;
Transfer transfer; //thus Endpoint contains an instance of "Transfer"
} Endpoint
点; 而转移本身的结构如下:
typedef struct {
char *pData;
volatile int buffered;
volatile int transferred;
volatile int remaining;
volatile TransferCallback fCallback;
void *pArgument;
} Transfer;
TransferCallback是一个具有以下原型的函数:
typedef void (*TransferCallback)(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining);
还有两个指针定义如下:
Endpoint *pEndpoint = &(endpoints[bEndpoint]);
Transfer *pTransfer = &(pEndpoint->transfer);
我想知道为什么这种调用函数TransferCallback的方法是有效的:
((TransferCallback) pTransfer->fCallback) (followed by the required arguments passed )
但这无效:
((TransferCallback)pEndpoint->transfer->fCallback)?
如何在不使用诸如pTransfer之类的指针的情况下直接调用TransferCallback? 我尝试了很多组合,但都没有效果。
答案 0 :(得分:4)
请注意,Endpoint
没有指向Transfer 成员的指针(*Transfer
),而是 Transfer 成员。在机器术语中,Endpoint
成员的所有字段都直接存储在<{1}}中,而不是每个Transfer
内的单个内存字1}} em>在为Transfer
分配的内存中。
要切入追逐,你需要的是:
Endpoint
答案 1 :(得分:0)
关于OP的标题:如何通过C中的指针调用函数
对于如何的问题,Alex回答了你的问题,但是为了了解为什么选择一个函数指针而不仅仅是提供正常的函数名称首先;函数指针在C *(参见*)中特别有用,当你有一组相似的函数时,它们包含相同的参数列表,但具有不同的输出。您可以定义一个函数指针数组,使其更简单,例如,从交换机或循环调用该系列中的函数,或者在池中创建包含一系列线程的函数时类似的工作者作为参数。调用数组就像更改指针索引一样简单,以获得每个唯一大小写所需的特定功能。 作为一个简单示例 ,两个字符串函数strcat()
和strcpy()
具有参数列表:(char *, const char *)
因此,可以分配给函数指针数组。首先创建函数指针数组:
char * (*pStr[2])( char *a, const char *b);` //array of function pointers pStr[]
然后,将strcat和strcpy的分配给数组:
void someFunc(void)
{
pStr[0] = strcat; //assign strcat to pointer [0]
pStr[1] = strcpy; //assign strcpy to pointer [1]
}
现在,strcat()
或strcpy()
可以被称为:
int main(void)
{
char a[100]="kjdhlfjgls";
char b[100]="kjdhlfjgls";
someFunc();//define function pointers
pStr[0](a, "aaaaaaaa"); //strcat
pStr[1](b, "aaaaaaaa"); //strcpy
return 0;
}
示例输出 :
这只是一个简单的例子。它没有探索函数指针可以提供的有用程度,但说明了另一个原因为什么函数指针在某些情况下可能是首选。
* 此插图仅针对C ,而不是C ++,其中该语言固有的继承和多态的质量会使这个建议没必要。