4

私が理解しなければならない埋め込みコードには、次のコード行があります。

*((void (**) ()) 0x01) = c_int01; /* Write the interrupt routine entry */

関数ポインタで割り込みベクトルを設定していることは把握できますが、c_int01どのようなキャスト(void (**) ())を指しているのかわかりません。標準の関数ポインタ表記は知っています(void (*)())が、他のものは知りません。

次のようにもう少し読みやすくなるように、コードをリファクタリングしようとしました。

// header
typedef void (*interrupt_handler)(); // prototype of an interruption handler
#define INTERRUPT_VECTOR 0x01
#define SET_INTERRUPT_HANDLER( handler ) *((interrupt_handler) INTERRUPT_VECTOR) = (handler)

// code
SET_INTERRUPT_HANDLER( c_int01 );

しかし、組み込みコンパイラは、LHS がオブジェクトではないことについて泣き言を言います。

この表記が何を意味するか知っている人はいますか?(void (**)())

// 編集:

興味のある人にとっては、これをよりよく理解できます。

*( (void (*)())* 0x01) = c_int01;
4

5 に答える 5

10

これは、ポインタから関数へのポインタです。

したがって、キャストは整数0x01を型を持つ関数ポインタのアドレスに変換します(void (*)())

あなたはそれを書き換えることができます:

typedef void (*interrupt_handler)();
*((interrupt_handler*) 0x01) = c_int101;
于 2013-04-29T10:39:03.973 に答える
4

(void (**) ())関数ポインタへのポインタです。

((void (*)())は関数へのポインタであるため、アスタリスクを追加すると、間接的なレベルが追加されます。)

あなたは言う必要があります:

*((interrupt_handler*) INTERRUPT_VECTOR) = (handler)

それは、 「関数ポインタへのポインタとして扱い、その値を に設定する」というものです。INTERRUPT_VECTORhandler

于 2013-04-29T10:40:03.350 に答える
2

これは、常に有用なcdeclがその式のコアについて述べていること(void (**) ())です。

unknown_name を void を返す関数へのポインタへのポインタにキャストします

したがって、これはキャスト (外側の括弧のペアによって示される) であり、型は「関数へのポインターへのポインター」であり、意味があるようです。

于 2013-04-29T10:41:15.497 に答える
1

Cdeclは、知るためのより迅速な方法です。

     cast unknown_name into pointer to pointer to function returning void

有名な「スパイラル ルール」は次のようになります。

          +-----+
          |+-+  |
          || |  V
   (void (** |)( ))
      ^   ^^||  |
      |   ||||  |
      |   ||+|  |
      |   +--+  |
      +---------+

あなたが読んだ行に従ってください:

  • へのポインタ
  • へのポインタ
  • 返す関数
  • 空所
于 2013-04-29T10:44:51.980 に答える
-1

割り込みエントリ ポイント ベクトルの設定を次のように視覚化できます。

   void (*interupt_handlers)()[256] = 0;

   void set_interupt_handler(int vector, void(*handler)())
   {
       interupt_handlers[vector] = handler;
   }
于 2013-04-29T11:40:32.077 に答える