Обтекание библиотеки libcups C в Swift - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь обернуть библиотеку libcups https://github.com/apple/cups для использования в моем проекте Swift.

Я пробовал некоторые примеры в https://www.cups.org/doc/cupspm.html, и они работают нормально.

Однако я испытываю трудности, когда дело доходит до переноса кода C в быть использованным в проекте Swift.

Я искал в Интернете, как обернуть C библиотеки в Swift, но не смог добиться большого прогресса.

Вот C code

#include <stdio.h>
#include <cups/cups.h>

typedef struct {
    int num_dests;
    cups_dest_t *dests;
} my_user_data_t;

int my_dest_cb(my_user_data_t *user_data, unsigned flags, cups_dest_t *dest) {
    if (flags & CUPS_DEST_FLAGS_REMOVED) {
        user_data->num_dests = cupsRemoveDest(dest->name, dest->instance, user_data->num_dests, &(user_data->dests));
    } else {
        user_data->num_dests = cupsCopyDest(dest, user_data->num_dests, &(user_data->dests));
    }
    return 1;
}

int my_get_dests(cups_ptype_t type, cups_ptype_t mask, cups_dest_t **dests) {
    my_user_data_t user_data = { 0, NULL };

    if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type, mask, (cups_dest_cb_t)my_dest_cb, &user_data)) {
        cupsFreeDests(user_data.num_dests, user_data.dests);
        *dests = NULL;
        return 0;
    } else {
        *dests = user_data.dests;
        return user_data.num_dests;
    }
}

int main(int argc, const char * argv[]) {
    cups_dest_t *dests = NULL;
    int num_dests = my_get_dests(0, 0, &dests);
    printf("Destination found: %d\n", num_dests);

    cups_dest_t *dest;
    int i;
    const char *value;

    for (i = num_dests, dest = dests; i > 0; i--, dest++) {
        if (dest->instance == NULL) {
            value = cupsGetOption("printer-info", dest->num_options, dest->options);
            printf("%s (%s)\n", dest->name, value ? value : "No description");
        }
    }
    return 0;
}

Здесь то же самое, но в Swift

let destinationsCallback: cups_dest_cb_t = { user_data, flags, dest in
    // (void *user_data, unsigned flags, cups_dest_t *dest)
    var userDataPointer = user_data!.assumingMemoryBound(to: my_user_data_t.self).pointee
    var destData = dest!.pointee

    if destData.instance != nil {
        print("\(String(cString: destData.name))/\(String(cString: destData.instance))")
    } else {
        print(String(cString: destData.name))
    }

    if flags == CUPS_DEST_FLAGS_REMOVED {
        userDataPointer.num_dests = cupsRemoveDest(destData.name, destData.instance, userDataPointer.num_dests, &(userDataPointer.dests))
    } else {
        userDataPointer.num_dests = cupsCopyDest(dest, userDataPointer.num_dests, &(userDataPointer.dests))
    }
    return 1
}

func getDestinations(type: UInt32, mask: UInt32, dests: UnsafeMutablePointer<cups_dest_t>) -> Int32 {
    var userData = my_user_data_t(num_dests: 0, dests: nil)

    if cupsEnumDests(UInt32(CUPS_DEST_FLAGS_NONE), 1000, nil, type, mask, destinationsCallback, &userData) != 1 {
        return 0
    } else {
        return userData.num_dests
    }
}

Я не могу получить userData, чтобы вернуть правильное значение, которое я предполагаю, из-за того, как я обращаться с указателями.

Буду очень признателен, если смогу получить совет.

1 Ответ

0 голосов
/ 24 февраля 2020

ИМХО лучший способ работы с такими C библиотеками в Swift - это работать с ними в Objective- C. Тем не менее, основная проблема заключается в том, что вы не записываете изменения в userData, поэтому вы всегда получаете исходное значение. Вам необходимо обновить его в вашем обратном вызове следующим образом

let userDataPointer = user_data!.assumingMemoryBound(to: my_user_data_t.self)
var userData = userDataPointer.pointee
...
// make some changes to userData

userDataPointer.pointee = userData

return 1

Также, похоже, есть некоторые различия между вашим C кодом и кодом Swift, например проверка флагов с помощью 'flags == CUPS_DEST_FLAGS_REMOVED', которая в Вообще, неверный способ проверки флагов и сравнение результата cupsEnumDests с 1, когда в исходном коде вы проверяете, что результат не равен 0.

...