1

プログラムの SIGINT 呼​​び出しで使用できるように、いくつかの追加の引数を渡そうとしていますが、コンパイル エラーが発生します。これは実際に達成可能ですか?

それが達成可能であれば、誰かがここで私の間違いを説明してもらえますか;

void signal_handler(bool &txMode, char* &txData, int &sendresult, int &sockFD,_
char* &txBuffer, struct sockaddr_ll &socket_address);

int main(int argc, char *argv[]) {
    unsigned char sourceMAC[6];
    unsigned char destMAC[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    bool txMode = true;
    char* txBuffer = (char*)operator new(ETH_FRAME_LEN);
    unsigned char* txEtherhead = (unsigned char*)txBuffer;
    struct ethhdr *eh = (struct ethhdr *)txEtherhead;
    int sockFD;
    char* txData = txBuffer + headersLength;
    struct sockaddr_ll socket_address;
    int sendresult = 0;

    signal (SIGINT,signal_handler(txMode, txData, sendresult, sockFD, txBuffer,_
    socket_address));

    return 0;
}

void signal_handler(bool &txMode, char* &txData, int &sendresult, int &sockFD,_
char* &txBuffer, struct sockaddr_ll &socket_address) {

  if(txMode==true) {
    std::string param;
    std::stringstream ss;
    ss << "etheratedeath";
    param = ss.str();
    strncpy(txData,param.c_str(), param.length());
    sendresult = sendto(sockFD, txBuffer, ETH_FRAME_LEN, 0, 
             (struct sockaddr*)&socket_address, sizeof(socket_address));
  }
  cout << "You killed me!" << endl;
}

コンパイル時に次のエラーが発生します。

user@machine:~/c/ethernet1$ gcc -o ethernet1 ethernet1.cpp -lrt
ethernet1.cpp: In function ‘int main(int, char**)’:
ethernet1.cpp:358: error: invalid use of void expression

これは main(); のこの行を参照します。

signal (SIGINT,signal_handler(txMode, txData, sendresult, sockFD, txBuffer, socket_address));
4

3 に答える 3

2

これは実際に達成可能ですか、それとも誤解されていますか?

これが機能するには、クロージャと呼ばれる構造が必要です。C にも C++ にもクロージャは組み込まれていません。ただし、ffcallライブラリを使用してクロージャの動作を実装できます。アイデアは、汎用ハンドラーとその関数に渡される引数からその場関数を構築することです。もちろん、引数は、スコープが残っていても有効なままでなければなりません。つまり、それらをグローバル変数にするか、ヒープに割り当てます。

コンパイル時に次のエラーが発生します。(...)

signal (SIGINT,signal_handler(txMode, txData, sendresult, sockFD, txBuffer, socket_address));

ここで、そこに何を書き、コンパイラがこれをどのように解釈するかを考えてください。関数パラメーターは値渡しです。したがって、式 signal_handler(...) が評価され、結果が signal に渡されます。これはあなたが望むものではありません.SIGINTが到着したときに渡された引数でsignal_handlerが呼び出されることを望みます. しかし、これは、この行が表現するものではありません。それが表現することは次のとおりです。ここでパラメーターを指定して signal_handler を呼び出し、その結果をハンドラー パラメーターとして渡して、後で SIGINT が到着したときに呼び出すためのシグナルを送信します。

于 2012-08-21T19:59:35.463 に答える
0

を呼び出す場合、シグナル ハンドラを呼び出すsignalのではなく、特定のシグナルを適切なハンドラに関連付けます。

だからあなたの電話は

signal(SIGINT,&signal_handler);

次に、signal_handler を次のように定義する必要があります。

typedef void (*sighandler_t)(int);

これは、1 つの引数 (シグナル番号) のみを使用する関数です。さらに、シグナルがプログラムの外部に発行されるため、追加のパラメーターを渡すことはできません。

于 2012-08-21T19:59:35.687 に答える
-1

私の知る限り、signal は int 引数を持つ void 関数へのポインタを取ります。私はあなたを可能にするオーバーロードを知りません。

http://www.cplusplus.com/reference/clibrary/csignal/signal/

于 2012-08-21T19:50:58.207 に答える