2016-12-26 13 views
0

Hallo Ich werde mit ThirdParty-Bibliothek (.so-Datei) mit Golang in Linux-Umgebung arbeiten. Also habe ich versucht, etwas mit etwas Trivialem zu üben, wie zum Beispiel das Importieren von Funktionen aus Linux-nativen Bibliotheken. Und blieb beim Import und Aufruf der sqrt-Funktion hängen. Hier ist mein Code:Golang C (.so) importiert Segmentierungsverletzung bei Aufruf

package main 
     // #cgo LDFLAGS: -ldl 
     // #include <dlfcn.h> 
     // #include <stdio.h> 
     import "C" 
     import "fmt" 

     func main() { 


      export_name := "sqrt" 
      lib_path := "/lib/libm.so.6" 

      //Loading .so 
      handle := C.dlopen(C.CString(lib_path), C.RTLD_LAZY) 
      if handle == nil { 
       fmt.Println(lib_path+":\tNOT FOUND") 
       return 
      } else { 
       fmt.Println(lib_path+":\tSUCCESS") 
       } 

      //looking for function address 
      func_pointer := C.dlsym(handle, C.CString(export_name)) 
      if func_pointer == nil { 
       fmt.Println(export_name+":\tNOT FOUND") 
       return 
      } else { 
       fmt.Println(export_name+":\t", func_pointer) 
       } 

      //negotiating datatypes 
      //From c lib description: double sqrt(double x); 
      sqrt := *(*(func(float64)float64))(func_pointer) 

      //Calling function 
      sqrt(4) 

     } 

, wenn ich es laufen, habe ich immer Segmentierungsverletzung erhalten:

/lib/libm.so.6: SUCCESS 
sqrt: 0x7f37117ea270 
unexpected fault address 0x0 
fatal error: fault 
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x4019fa] 

goroutine 1 [running]: 
runtime.throw(0x4a6643, 0x5) 
     /usr/lib/go/src/runtime/panic.go:566 +0x95 fp=0xc42004be00 sp=0xc42004bde0 
runtime.sigpanic() 
     /usr/lib/go/src/runtime/sigpanic_unix.go:27 +0x288 fp=0xc42004be58 sp=0xc42004be00 
main.main() 
     /home/afx/goc/so.go:37 +0x2ba fp=0xc42004bf48 sp=0xc42004be58 
runtime.main() 
     /usr/lib/go/src/runtime/proc.go:183 +0x1f4 fp=0xc42004bfa0 sp=0xc42004bf48 
runtime.goexit() 
     /usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42004bfa8 sp=0xc42004bfa0 

goroutine 17 [syscall, locked to thread]: 
runtime.goexit() 
     /usr/lib/go/src/runtime/asm_amd64.s:2086 +0x1 
exit status 2 

Was ist das Problem? Vielen Dank im Voraus.

P.S. Wenn ich Funktionszeiger von nativen Go-Funktionen (wie hier Go: convert unsafe.Pointer to function pointer and vice versa) neu definiere, funktioniert alles gut. Aber der Import schlägt fehl.

+0

Ich glaube nicht, dass Sie es auf diese Weise tun können. Sehen Sie sich dieses Beispiel an, Sie können es mit einer statischen Brückenfunktion tun https://github.com/coreos/pkg/blob/master/dlopen/dlopen_example.go –

+0

Vielen Dank! Brückenfunktion war das fehlende Glied. – alex

Antwort

0

Hier ist die Lösung. Ich hatte Brücke C-Funktion:

package main 

// #cgo LDFLAGS: -ldl 
// #include <dlfcn.h> 
// #include <stdio.h> 
// 
// double 
// my_sqrt_bridge(void *f, double x) 
// { 
// //description: ((return_data_type (*)(input_data_type))bridge_input_function_pointer) (bridge_input_value) 
// return ((double (*)(double))f)(x); 
// } 
import "C" 
import "fmt" 

func main() { 

    export_name := "sqrt" 
    lib_path := "/lib/libm.so.6" 

    //Loading .so 
    handle := C.dlopen(C.CString(lib_path), C.RTLD_LAZY) 
    if handle == nil { 
     fmt.Println(lib_path + ":\tNOT FOUND") 
     return 
    } else { 
     fmt.Println(lib_path + ":\tSUCCESS") 
    } 

    //looking for function address 
    func_pointer := C.dlsym(handle, C.CString(export_name)) 
    if func_pointer == nil { 
     fmt.Println(export_name + ":\tNOT FOUND") 
     return 
    } else { 
     fmt.Println(export_name+":\t", func_pointer) 
    } 

    fmt.Printf("%f", C.my_sqrt_bridge(func_pointer, 2)) 

} 
0

Wäre es in Ihrem Fall möglich sein CGO lassen die Bibliothek für Sie verknüpfen? ZB:

package main 

/* 
#cgo LDFLAGS: -lm 
#include <math.h> 
*/ 
import "C" 
import "fmt" 

func main() { 
    fmt.Printf("%g\n", C.sqrt(2)) //prints 1.4142135623730951 
} 

Für einen Dritten Bibliothek /some/lib/dir/libxxx.so:

LDFLAGS: -L/some/lib/dir -lxxx 
Verwandte Themen