1

Py++によって生成されたC++プログラムに奇妙なtypedefステートメントがあります。

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

私がこれまでに理解したことは、上記のtypedef statemntはそのタイプではないということです。私たちのほとんどは、

typedef complex_type simple_alias;

むしろ、intを引数として取り、doubleを返す関数へのポインタを宣言する方法です(プロトタイプと同じ)。だから私の質問は、関数のアドレスを引数として(逆参照せずに)関数へのポインタがどのように呼び出されるのかということです。これもプロトタイプとは一致しません。誰か説明してください!

4

5 に答える 5

6

関数ポインター変数を宣言していませんが、関数ポインター typedef が呼び出されていradius_function_typeます。radius_function_type(&radius)関数ポインター自体の単なる(冗長な)キャストです。(単項&アドレス演算子も冗長です。関数の場合、radius&radiusは同じものです。)

低レベルでは、関数の呼び出しは、基になる呼び出し規則に従って引数をどこかに配置し (通常はスタック上)、メモリ アドレスにジャンプするだけです。したがって、関数ポインターの型 (関数シグネチャ) とポインター値自体がわかっている場合、コンパイラーはポインターだけで関数を呼び出すことができます。

于 2009-06-03T12:47:07.647 に答える
3

あなたの質問は紛らわしいです。これが何をするのか尋ねていますか:

radius_function_type(&radius)"

これは単なる C++ 型キャストで、次のようなものです。

radius (int (42));

ただし、radius は既に radius_function_type 型であるため、次のように簡単に実行できます。

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

ただし、これは Py++ によって生成されたコードであるため、出力には特に注意を払っている可能性があります。

于 2009-06-03T12:51:39.307 に答える
2

ええと...これは、CおよびC ++で、配列がポインターにどのように関連しているかに少し似ています。関数の名前も基本的にはポインタです。その観点から見ると、次のような定義が与えられても驚くことではありません。

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

関数の名前であるポインターを介して、直接呼び出すことができます。

foo(1, 2);

または、その値を別の変数に格納します。この変数は、ポインターとして宣言する必要があります。

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

この場合、ポインタ変数を直接呼び出すことができます。また、を記述して関数の「アドレスを取得」する必要もありません&foo

于 2009-06-03T12:38:49.533 に答える
1

関数ポインタは基本的に、呼び出す必要がある関数のアドレスです。関数ポインターが指す関数を呼び出すには、関数ポインターを、呼び出したい関数の名前であるかのように考えます。それ自体を呼び出す行為は逆参照を実行します。明示的な逆参照は必要ありません。

関数ポインタの構文は、(& と * を使用して) ポインタのように見えることもあれば、省略されることもあります。@unwind既に指摘したように、裸の配列がポインターに似ている場合の配列の処理方法に似ており、オプションで配列の前に & を付けてアドレスを取得できます。

于 2009-06-03T12:55:56.520 に答える
1

関数のポインターを (あなたが考える方法で) 逆参照することは、DATA メモリーと同じように CODE メモリーにアクセスすることを意味します。

関数ポインターは、そのように逆参照されるとは想定されていません。代わりに呼び出されます。

「呼び出し」と並べて「逆参照」という名前を使用します。大丈夫です。

とにかく、Cは、関数名識別子と変数保持関数のポインタの両方が同じ意味を持つように設計されています:CODEメモリへのアドレス。また、識別子または変数で call () 構文を使用して、そのメモリにジャンプできます。

于 2009-06-03T12:46:47.227 に答える