AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found; running Go from Python using C

AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found; running Go from Python using C

我有以下 go 文件:

//try_async.go
package main

import (
    "C"
    "fmt"
    "math/rand"
    "sync"
    "time"
)

var mutex sync.Mutex
var wg sync.WaitGroup

func random_sleep() {
    r := rand.Intn(3000)
    time.Sleep(time.Duration(r) * time.Millisecond)
}


func add_to_map(m map[string] string, word string) {
    defer wg.Done()
    added_word := word + " plus more letters"
    fmt.Println("Before sleep")
    random_sleep()
    mutex.Lock()
    defer mutex.Unlock()
    m[word] = added_word
    fmt.Println("Added word %v", word)
}

// export add_all_items_to_map
func add_all_items_to_map(words []string) map[string]string {
    words_map := make(map[string]string)
    for _, this_word := range words {
        wg.Add(1)
        go add_to_map(words_map, this_word)
    }
    wg.Wait()
    return words_map
}


func main() {
    // result := add_all_items_to_map([]string{"cat", "dog", "fish"})
    // fmt.Println(result)
}

我有 Python 脚本:

from ctypes import cdll

"""
run

  go build -buildmode=c-shared -o try_async.so try_async.go

first
"""

lib = cdll.LoadLibrary('./try_async.so')

print("Loaded go lib")
result = lib.add_all_items_to_map(['cat', 'dog', 'fish'])
print(result)

结果是奇怪的错误,别人说的是你没有构建共享对象,但我做了:

cchilders:~/work_projects/golang_integration (feature/golang-query) 
$ rm *.so

cchilders:~/work_projects/golang_integration (feature/golang-query) 
$ go build -buildmode=c-shared -o try_async.so try_async.go

cchilders:~/work_projects/golang_integration (feature/golang-query) 
$ python go-async-caller.py 
Loaded go lib
Traceback (most recent call last):
  File "go-async-caller.py", line 14, in <module>
    result = lib.add_all_items_to_map(['cat', 'dog', 'fish'])
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 375, in __getattr__
    func = self.__getitem__(name)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 380, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found

以下内容有效:

libadd.go-

//libadd.go
package main

import "C"

//export add
func add(left int, right int) int {
    return left + right
}

func main() {}

go-caller-example.py-

from ctypes import cdll

"""
run

  go build -buildmode=c-shared -o libadd.so libadd.go

first
"""

lib = cdll.LoadLibrary('./libadd.so')

print("Loaded go lib")
result = lib.add(2, 3)
print(result)

像这样

cchilders:~/work_projects/golang_integration (feature/golang-query) 
$ go build -buildmode=c-shared -o libadd.so libadd.go

cchilders:~/work_projects/golang_integration (feature/golang-query) 
$ python go-caller-example.py 
Loaded go lib
5

http://savorywatt.com/2015/09/18/calling-go-code-from-python-code/

Go 中的指令有点脆弱,您需要完全正确地设置它们,否则它们会悄无声息地失败。

在这种情况下你有这个:

// export add_all_items_to_map

但需要这个:

//export add_all_items_to_map

有关详细信息,请参阅 the cgo docs