2017-05-19 13 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のリンクをgoコード、Cのエクスポート/エクスターナルにリンクする必要がありますか?

最初にC-ishにすることなく、go機能をコールバック機能にする方法はありませんか?

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

答えて

0

キャストを回避し、コールバックコードを単純化する方法がいくつかあります。私は.Cする.GOからコードを移動するので、それは、キャストせずに直接goCallbackFunctionを参照.But

// 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) 
    } 
} 
    C.InitCallback
  1. 関数はC.SomeDLLFuncと同様です。
  2. これはc dllから行くコールバックについての解決策です。 dllには1つのgo関数しか登録する必要はありません。私たちは1つ書きますC.InitCallbackC.SomeDLLFuncソリューションを使用する場合は、(gocallback、dllfunc)のペアを記述する必要があります。
  3. c dllにエクスポート関数ポインタを保持することはOKです。
関連する問題