0

我一直在浏览 AT91SAM7 的 Atmel 库 USB,有些东西我不明白。Endpoint 是一个结构体,定义如下:

typedef struct {
    volatile unsigned char  state;
    volatile unsigned char  bank;
    volatile unsigned short size;
    Transfer       transfer;        //thus Endpoint contains an instance of "Transfer"  
} Endpoint

观点; 而Transfer本身是一个结构如下:

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?我尝试了多种组合,但都没有奏效。

4

2 回答 2

4

请注意,Endpoint它没有指向 Transfer成员 ( *Transfer) 的指针,而是一个Transfer成员。用机器术语来说,不是将每个内存中的单个字Endpoint用作指向 a 的指针,而是将成员的Transfer所有字段直接存储在为 分配的内存中。TransferEndpoint

切入正题,您需要的是:

((TransferCallback)pEndpoint->transfer.fCallback)

于 2013-11-02T20:17:18.313 回答
0

关于 OP 的标题:如何在 C 中通过指针调用函数

+1 亚历克斯对您关于How的问题的回答,但为了了解为什么选择函数指针而不是首先提供普通函数名称,可以提出另一点;当您拥有一组相似的函数时,函数指针在 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++ 相对,在 C++ 中,该语言固有的继承和多态特性使该建议变得不必要。

于 2013-11-02T21:19:06.080 回答