Недопустимый параметр функции

#c #sockets #function-pointers

#c #сокеты #указатели на функции

Вопрос:

Я пишу C-код, в котором я использую сокеты. Я использую это в Windows и Linux, поэтому я стараюсь писать это динамично. Я написал две функции, чтобы получить серверный / клиентский сокет. Там у меня ошибка при компиляции:

 debian:~/cross_socket# make
gcc *.c -Wall
i586-mingw32msvc-gcc *.c -Wall -lws2_32
socket.c: In function 'get_client_socket':
socket.c:28: warning: passing argument 3 of 'get_socket' from incompatible pointer type
socket.c:13: note: expected 'int (*)(SOCKET,  const struct sockaddr *, int)' but argument is of type 'int (*)(SOCKET,  const struct sockaddr *, int)'
socket.c: In function 'get_server_socket_addr':
socket.c:43: warning: passing argument 3 of 'get_socket' from incompatible pointer type
socket.c:13: note: expected 'int (*)(SOCKET,  const struct sockaddr *, int)' but argument is of type 'int (*)(SOCKET,  const struct sockaddr *, int)'
  

gcc для моей локальной системы работает отлично, но если я использую mingw, я получаю эту ошибку ?!?
В нем говорится:
Я использую int (*)(SOCKET, const struct sockaddr *, int) вместо int (*)(SOCKET, const struct sockaddr *, int) … ?

Здесь соответствующий код:

 inline SOCKET get_socket(uint16_t port, in_addr_t socket_in_addr, int (*create)(SOCKET, 
const struct sockaddr*, socklen_t)) {
        SOCKADDR_IN addr;
        SOCKET result_socket = GET_SOCKET;
        if (SOCKET_NOK(result_socket))
                return SOCKET_INIT_ERROR;
        memset(amp;addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = socket_in_addr;
        if (CONNECT_NOK(create(result_socket, (SOCKADDR*)amp;addr, sizeof(SOCKADDR))))
                return SOCKET_INIT_ERROR;
        return result_socket;
}

SOCKET get_client_socket(char* target, uint16_t port) {
        return get_socket(port, inet_addr(target), amp;connect);
/*      SOCKADDR_IN addr;
        SOCKET client_socket = GET_SOCKET;
        if (SOCKET_NOK(client_socket))
                return SOCKET_INIT_ERROR;
        memset(amp;addr,0,sizeof(SOCKADDR_IN));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = inet_addr(target);
        if (CONNECT_NOK(connect(client_socket, (SOCKADDR*)amp;addr, sizeof(SOCKADDR))))
                return SOCKET_INIT_ERROR;
        return client_socket;*/
}

SOCKET get_server_socket_addr(uint16_t port, in_addr_t socket_in_addr) {
        return get_socket(port, socket_in_addr, amp;bind);
/*      SOCKADDR_IN addr;
        SOCKET server_socket = GET_SOCKET;
        if (SOCKET_NOK(server_socket))
                return SOCKET_INIT_ERROR;
        memset(amp;addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = socket_in_addr;
        if (CONNECT_NOK(bind(server_socket, (SOCKADDR*)amp;addr, sizeof(SOCKADDR_IN))))
                return SOCKET_INIT_ERROR;
        return server_socket;*/
}
  

У кого-нибудь есть идея?

Ответ №1:

Вероятно, вызывается неправильное соглашение.

В Windows большинство функций API определяются как WINAPI , то есть __stdcall на языке PASCAL. т.е. параметры передаются слева направо, а вызываемый объект очищает стек.

Соглашение о вызове компиляции по умолчанию является OTOH __cdecl .

P.S. Было бы неплохо, если бы mingw напечатал более подробную информацию об ошибке.

Ответ №2:

Если «connect» — это функция, вы должны просто передать ее как «connect», а не «amp;connect». Имя функции уже является указателем на нее.

Комментарии:

1. Хорошо, я попробовал это, но это создает тот же результат. Мой локальный gcc компилирует его, но mingw нет.