DllImport - PreserverSig и атрибуты SetLastError

Существует несколько ошибок и предупреждений, выданных компилятором для вашего кода.

Но я полагаю, что решающим фактором было то, что вы делали,

 sock_fd = listen(sock_fd, 1);

, что должно быть,

 listen(sock_fd, 1);

И что вы использовали команду сокета с неинициализированной переменной .

// sock_fd = socket(domain, type, 0); // wrong
(sock_fd=socket(AF_INET,SOCK_STREAM,0); // correct

Следующие настройки также отсутствовали,

// The following three lines were missing
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(PORT);

Вот полный код с большим количеством исправлений, в котором все еще есть некоторые предупреждения о неиспользуемых переменных и т. Д., Но, по крайней мере, все идет " быть готовым к принятию соединений. "

Вы должны действительно включить все возможные предупреждения на вашем компиляторе и прочитать книгу сетевого программирования Биджа .

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 4444

int main(void) {
    // Declare initial values;
    int domain, sock_fd, type;
    struct sockaddr_in localAddr;

    // The following three lines were missing
    localAddr.sin_family = AF_INET;
    localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    localAddr.sin_port = htons(PORT);

    socklen_t addr_length;

    // sock_fd = socket(domain, type, 0);
    //////////////////////Creating a SOCKET/////////////////////////
    if((sock_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        printf("ERROR:Socket failed\n");
        return -1;
    }

    if (bind(sock_fd, (struct sockaddr *) &localAddr, sizeof(struct sockaddr)) == -1)
    {
        printf("ERROR:Binding on server\n");
        close(sock_fd);
        return -1;
    }

    // Setup listening
    listen(sock_fd, 1);
    char buffer[1024];
    int sin_size, recv_len;
    while (1) {
        int client_fd;
        struct sockaddr_in clientAddr;
        sin_size = sizeof(clientAddr);
        client_fd = accept(sock_fd, NULL, NULL);
        if (client_fd == -1) {
            printf("Could not accept new connection");
            exit(-1);
        }
        close(client_fd);
    }
    close(sock_fd);
    return 0;
}

9
задан Shay Erlichmen 18 April 2009 в 17:00
поделиться

1 ответ

Функции Win32 почти никогда не возвращают HRESULT . Вместо этого они возвращают BOOL или используют специальные значения для указания ошибки (например, CreateFile возвращает INVALID_HANDLE_VALUE ). Они хранят код ошибки в переменной для каждого потока, которую вы можете прочитать с помощью GetLastError () . SetLastError = true инструктирует маршалера прочитать эту переменную после возврата нативной функции и спрятать код ошибки, где вы сможете позже прочитать его с помощью Marshal.GetLastWin32Error () . Идея состоит в том, что среда выполнения .NET может вызывать другие функции Win32 за кулисами, которые путают код ошибки из вашего вызова p / invoke, прежде чем вы получите возможность его проверить.

Функции, которые возвращают HRESULT (или эквивалентный, например, NTSTATUS ) относятся к другому уровню абстракции, чем функции Win32. Обычно эти функции связаны с COM (выше Win32) или из ntdll (ниже Win32), поэтому они не используют код последней ошибки Win32 (хотя они могут вызывать функции Win32 внутри системы).

PreserveSig = false инструктирует маршалера проверять возврат HRESULT и, если это не код успеха, создать и выдать исключение, содержащее HRESULT . Затем управляемое объявление вашей функции ed DllImport имеет тип возврата void .

Помните, что компилятор C # или VB не может проверить функцию ed DllImport неуправляемая подпись, поэтому она должна доверять тому, что вы ей говорите. Если вы поместите PreserveSig = false в функцию, которая возвращает что-то отличное от HRESULT , вы получите странные результаты (например, случайные исключения). Если вы поместите SetLastError = true в функцию, которая не устанавливает последний код ошибки Win32, вы получите мусор вместо полезного кода ошибки.

14
ответ дан 4 December 2019 в 14:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: