방법

2011-08-04 4 views
4
여기

방법

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

가 어떻게 이동에서이 함수를 호출 할이 C 함수 선언을 인 (CGO 도구)로 이동 언어에서이 C 함수를 호출하는 방법?

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, ????)) 
} 

답변

4

직접 호출 할 수 없습니다. CGO는 C 측에서 vararg 함수와 잘 작동하지 않습니다. 이상적으로, 전달하려는 옵션 목록을 허용하는 C 랩퍼를 작성할 수 있습니다. C 함수는 그 목록을 curl_easy_set_opt()이 필요로하는 가변 인수로 확장해야합니다. 그러나 그것이 가능한지 또는 어떻게해야하는지에 대해서는 확신 할 수 없습니다.

당신의 이동 기능에 대한 서명도 잘못 : 옵션 매개 변수의 유형이 그것의 이동 버전으로 변경되었습니다

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))) 
} 

하는 것으로. 누군가 당신의 패키지를 사용할 때 그들은 C.xxx 타입에 접근 할 수 없다. 그래서 당신은 당신의 공공 API에서 그것들을 사용해서는 안됩니다. 그들은 오직 당신의 패키지에 내부 사용을위한 것입니다.