как вызвать эту функцию C из языка Go (с помощью инструмента Cgo) - PullRequest
4 голосов
/ 04 августа 2011

Вот это объявление функции C

CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);

как мне вызвать эту функцию из Go?

type Easy struct {
    curl unsafe.Pointer
    code C.CURLcode
}

func (e *Easy)SetOption(option C.CURLoption, ...) {
    e.code = C.curl_easy_setopt(e.curl, option, ????))
}

1 Ответ

4 голосов
/ 04 августа 2011

Вы не можете позвонить напрямую.CGO плохо работает с функциями vararg на стороне C.В идеале вы можете создать оболочку C, которая принимает список опций, которые вы хотите передать.Функция C должна затем развернуть этот список в переменные аргументы, необходимые для curl_easy_set_opt().Но я не уверен, возможно ли это или как это сделать.

Подпись для вашей функции Go также неверна:

type Option C.CURLoption

func (e *Easy) SetOption(options ...Option) {
    // 'options' is now accessible as a slice: []Option
    // Turn this slice into a list of C.CURLoption pointers and pass it to
    // your C wrapper.

    if len(options) == 0 {
        return // No use continuing.
    }

    // Here is one way to convert the option slice to a list
    // that C can work with.
    size := int(unsafe.Sizeof(options[0]))
    list := C.malloc(C.size_t(size * len(options)))
    defer C.free(unsafe.Pointer(list)) // Free this after use!

    for i := range options {
        ptr := unsafe.Pointer( uintptr(list) + uintptr(size * i) )
        *(*C.CURLoption)(ptr) = C.CURLoption(options[i])
    }

    C.my_setopt_wrapper(e.curl, list, C.int(len(options)))
}

Обратите внимание, что тип параметра optionбыла изменена на версию Go.Когда кто-то использует ваш пакет, у него нет доступа к типам C.xxx.Таким образом, вы не должны использовать их в своем публичном API.Они предназначены только для внутреннего использования в вашей упаковке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...