プロが教える店舗&オフィスのセキュリティ対策術

皆様、よろしくお願いしたします。RedHat9上で
次のような「鬼ごっこのプログラム」server.cをコンパイルしています。

$ g++ -o server server.c
server.c: function 内の `void session_init(int, char, int, int, char, int,
int)':
server.c:134: invalid conversion from `void (*)()' to `void (*)(int)'

というエラーが出てしまいます。
134行というと
「 signal(SIGINT, die);」
なのですが何が間違っているんでしょうか?

A 回答 (2件)

signal の使い方を見ればすぐにわかりますが,


void die()
ではなく
void die(int sig)
としなければなりません.

この回答への補足

ご回答ありがとうございます。

> signal の使い方を見ればすぐにわかりますが,
> void die()
> ではなく
> void die(int sig)
> としなければなりません.

static void die(int sig);

/* session モジュールの初期化 */
void session_init(int soc,
char mc, int mx, int my,
char pc, int px, int py)
/* soc ソケットのディスクリプタ */
/* mc 自分の表示用の文字 */
/* mx 自分の初期x座標 */
/* my 自分の初期y座標 */
/* pc 相手の表示用の文字 */
/* px 相手の初期x座標 */
/* py 相手の初期y座標 */
{
/* 初期データの設定 */
session_soc = soc;
width = soc + 1;
FD_ZERO(&mask);
FD_SET(0, &mask);
FD_SET(session_soc, &mask);
me.look = mc;
peer.look = pc;

me.x = mx; me.y = my;
peer.x = px; peer.y = py;

/* curses の初期化 */
initscr();
signal(SIGINT, die);
 という具合に

「static void die;」

「static void die(int sig);」
書換えましたら

$ g++ -o server server.c
server.c: function 内の `void session_loop()':
server.c:106: too few arguments to function `void die(int)'
server.c:186: ファイルのこの位置
server.c: トップレベル:
server.c:106: `void die(int)' が使われましたが未定義です

となっていました。

勘違いしてますでしょうか?





#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t sighandler);

というのを見つけました。

int型引数・void型返値の関数へのポインタをsighandler_t型に定義。

signal関数を

int型変数signum



sighandler_t型変数sighandler

の2つを引数にとるsighandler_t型返値の関数に定義。

という意味ですよね?

補足日時:2004/10/12 20:48
    • good
    • 0
この回答へのお礼

有難うございます。

お礼日時:2004/10/14 00:56

die の宣言を


void die(int sig);
にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ.

また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為.

この回答への補足

お手数をお掛けしています。


> die の宣言を
> void die(int sig);
> にしたのであれば, session_loop の中で die を呼出すときにも引数は必要ですよ.
> また, 最後の die の定義のところでも引数を取るようにしていますよね? ←念の為.

$g++ -o server server.c
server.c: function 内の `void session_init(int, char, int, int, char, int,
int)':
server.c:134: void の値が本来の意味通りに無視されませんでした

となってしまいました。
何か勘違いしてますでしょうか??



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <curses.h>
#include <signal.h>
#include <unistd.h>

#define BUF_LEN 20
#define MIN_X 1
#define MIN_Y 1
#define MAX_X 60
#define MAX_Y 20

/* 移動キーの割り当て */
#define NORTH 'k'
#define SOUTH 'j'
#define EAST 'l'
#define WEST 'h'
#define QUIT 'q'

#define PORT (in_port_t)50001
#define HOSTNAME_LENGTH 64

int setup_server(in_port_t port)
/* 戻り値 ソケットのディスクリプタ */
/* port 接続先のポート番号 */
{
struct sockaddr_in me; /* 自分のソケットのアドレス */
int soc_waiting; /* 接続待ちのソケット */
int soc; /* 通信に使うソケット */

/* 自分のアドレスを sockaddr_in 構造体に設定 */
memset((char *)&me, 0, sizeof(me));
me.sin_family = AF_INET;
me.sin_addr.s_addr = htonl(INADDR_ANY);
me.sin_port = htons(port);

/* IPv4 でストリーム型のソケットの作成 */
if ((soc_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0 ){
perror("socket");
return -1;
}

/* ソケットに自分のアドレスを設定 */
if (bind(soc_waiting,(struct sockaddr *)&me,sizeof(me)) == -1){
perror("bind");
return -1;
}

/* ソケットで接続待ちの設定 */
listen(soc_waiting,1);
fprintf(stderr,"successfully bound, now waiting.\n");

/* 接続要求があるまでブロック */
soc = accept(soc_waiting, NULL, NULL);

/* 接続待ちに使ったソケットを閉じる */
close(soc_waiting);

/* 通信に使うソケットのディスクリプタを返す */
return soc;
}
char * chop_newline(char *str, int len)
/* 戻り値 与えられた文字列の先頭アドレス */
/* str 改行文字で終わっているかも知れない文字列 */
/* len 処理の制限 */
{
int n = strlen(str); /* 与えられた文字列の長さ */

/* 末尾が改行文字なら削る */
if(n<len &&str[n-1]=='\n'){
str[n-1]='\0';
}

/* 先頭番地を返す */
return str;
}

/* プライベート変数 */
static int session_soc; /* socket */
static fd_set mask; /* fd mask */
static int width; /* width of the mask */
static char my_char, peer_char; /* character */

typedef struct{
int x,y; /* current position */
char look; /* character */
} PLAYER;

static PLAYER me, peer; /* 自分と相手の状態を保持する変数 */

static char buf[BUF_LEN]; /* 送受信兼用バッファ */

static WINDOW *win; /* 表示用ウィンドウ */

/* session モジュールにプライベートな関数 */
static void hide(PLAYER *who);
static void show(PLAYER *who);
static int update(PLAYER *who, int c);
static int interpret(PLAYER *who);
static void die(int);

補足日時:2004/10/14 00:36
    • good
    • 0
この回答へのお礼

有難うございます。

お礼日時:2004/10/14 00:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!