Question

J'ai une déclaration typedef bizarre dans un programme C ++, généré par Py ++.

double radius(int);  // function to be wrapped
typedef double (*radius_function_type)(int);    
bp::def("radius", radius_function_type(&radius));   // bp::def is a function for wrapping

Qu'est-ce que je me suis dit à ce jour est que le statemnt typedef ci-dessus ne sont pas du type, la plupart d'entre nous connaissent,

typedef complex_type simple_alias;

Au contraire, il existe un moyen de déclarer un pointeur vers une fonction qui prend comme argument int et renvoie deux (le même que le prototype). Donc, ma question est maintenant, comment se fait pointeur vers une fonction (sans déréférencement) de appelé avec l'adresse d'une fonction comme argument? Cela ne correspond pas aussi avec le prototype. Quelqu'un s'il vous plaît expliquer!

Était-ce utile?

La solution

Votre question est source de confusion. Demandez-vous ce que cela fait:

radius_function_type(&radius)"

Ceci est juste le transtypage d'un C, un peu comme:

radius (int (42));

mais comme rayon est déjà de type radius_function_type alors vous pouvez tout aussi bien faire:

bp::def("radius", radius);

mais comme cela est le code généré par Py ++, il est probablement être très prudent avec la sortie.

Autres conseils

Il ne déclare pas une variable de pointeur de fonction, mais un pointeur de fonction typedef appelé radius_function_type. radius_function_type(&radius) est juste un (redondant) exprimés pour le pointeur de la fonction elle-même. (Le & unaire adresse de l'opérateur est également redondant;. Pour une fonction, radius et &radius sont la même chose)

Sur un bas niveau, appelant une fonction est en train de placer les arguments quelque part en fonction de la convention d'appel (généralement sur la pile) sous-jacente, puis sauter à une adresse mémoire. Ainsi, le compilateur peut appeler une fonction avec juste un pointeur si elle connaît le type de pointeur de fonction (signature de la fonction) et la valeur de pointeur lui-même.

Eh bien ... Il est un peu similaire à la façon dont les tableaux sont liés à des pointeurs, en C et C ++. Le nom d'une fonction est essentiellement un pointeur, aussi. Vu de ce point de vue, il est pas trop surprenant que, étant donné une définition:

int foo(int a, int b)
{
  return a + b;
}

Vous pouvez faire l'appel soit directement, par le pointeur qui est le nom de la fonction:

foo(1, 2);

ou en stockant cette valeur dans une variable distincte, qui doit être déclarée comme un pointeur:

int (*pointer)(int, int) = foo;
pointer(1, 2);

Dans ce cas, on peut appeler par la variable pointeur directement, et il n'y a pas non plus besoin de explicitement « prendre l'adresse de » la fonction en écrivant &foo.

déréférencement (dans votre façon de penser) le pointeur de fonction signifie:. L'accès à une mémoire de CODE, car il serait une mémoire de données

pointeur de fonction est supposé ne pas être déréférencé de cette façon. Au lieu de cela, il est appelé.

J'utiliser un nom « déréférencement » côte à côte avec « appel ». Il est OK.

Quoi qu'il en soit: C est conçue de telle sorte que les deux identificateur de nom de la fonction, ainsi que le pointeur de fonction de maintien variables ont la même signification: adresse dans la mémoire de code. Et il permet de passer directement à la mémoire en utilisant la syntaxe appel () soit sur un identifiant ou variable.

pointeur de fonction est essentiellement l'adresse de la fonction qui doit être invoquée. Pour appeler la fonction pointée par un pointeur de fonction, on considère le pointeur de fonction comme si elle était le nom de la fonction que vous souhaitez appeler. L'acte de l'appeler lui-même effectue le déréférencement; il n'y a pas besoin de références explicites.

Syntaxe de pointeur de fonction peut ressembler à des pointeurs (avec & et *) ou qui peuvent être omis aussi bien. Comme @unwind déjà a souligné qu'il est similaire à la façon dont les tableaux sont traités où une kyrielle nue est similaire à pointeur et éventuellement vous pouvez préfixer le tableau avec et pour obtenir l'adresse.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top