2017-05-19 10 views
1

한 가지 방법은 DLL 함수에 매개 변수로 전달되는 콜백 함수는 CGO를 사용하는 것입니다 ... 콜백최소한의 Cgo로 DLL에 Go 콜백을 사용하는 방법은 무엇입니까? 설정에

typedef void (*TCallbackString)(char*); 

으로 정의된다

package main 

/* 
#cgo LDFLAGS: -L${SRCDIR} -lsomelib 

#include "somelib.h" 

extern void CallbackString(char* s); 
*/ 
import "C" 

import (
    "unsafe" 
    "fmt" 
) 

//export CallbackString 
func CallbackString(s *C.char) { 
    gostr := C.GoString(s) // convert to golang string 
    fmt.Println("Got string from dll (or dso): ", gostr) 
} 

func Example() { 
    // setup a callback by calling a function in 
    // the DLL requiring callback param 
    C.SomeDLLFunc(x,y, 
     (C.TCallbackString)(unsafe.Pointer(C.CallbackString)), 
     other, 
     params) 
} 


func main() { 
    Example() 
} 

그러나 나는 CGO 사용하지 그냥

C.SomeDLLFunc(x,y, 
    CallbackString, // how to send the go function in as a callback? 
    other, 
    params) 

는 항상합니까 즉 .. 불필요한 C 코드 바인딩을 필요로하지 않고 매개 변수로의 이동 기능을 전달하는 방법이 있는지 궁금 C 바인딩 또는 C 코드를 C 코드로 내보내기, C 코드를 내보내기/외부로 호출하여 콜백을 매개 변수로 보내야합니까?

C-ish를 먼저 만들지 않고 go 기능을 콜백으로 만드는 방법은 없습니다.

C.SomeDLLFunc(x,y, 
    WhatCastIsNeeded(CallbackString), // regular go function as a callback? 
    other, 
    params) 

답변

0

캐스트를 피하고 콜백 코드를 단순화하는 몇 가지 방법이 있습니다. 내가 .C하는 .go의 코드를 이동 이후는, 캐스트하지 않고 직접 goCallbackFunction를 참조 나누었다

// cgo.h in dll 
typedef void (*Callback)(int kind,void* arg); 
void SetCallback(Callback func); 

// cgo.c in dll 
Callback Gfunc; 
void SetCallback(Callback func){ 
    Gfunc=func; 
} 

// cgocb.h in go project 
void InitCallback(); 
extern void goCallbackFunction(int kind,void* arg); 

// cgocb.c in go project 
void InitCallback(){ 
    SetCallback(goCallbackFunction); 
} 

// cgocb.go in go project 
// export goCallbackFunction 
func goCallbackFunction(kind C.int,arg unsafe.Pointer){ 
    switch kind{ 
    case C.AKind: 
     arg:=(*C.AKind)(arg) 
     AkindCallback(arg) 
    } 
} 
  1. C.InitCallback 기능은 C.SomeDLLFunc 유사하다.
  2. 이것은 c dll에서 오는 콜백에 대한 해결책입니다. 우리는 dll에 하나의 go 함수 만 등록해야합니다. 우리는 하나의 C.InitCallback을 씁니다. C.SomeDLLFunc 솔루션을 사용하는 경우 (gocallback, dllfunc) 쌍을 작성해야합니다.
  3. c dll에서 내보내기 이동 기능 포인터를 유지하는 것이 좋습니다.