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

huangapple go评论82阅读模式
英文:

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/

英文:

I have the following go file:

//try_async.go
package main

import (
    &quot;C&quot;
    &quot;fmt&quot;
    &quot;math/rand&quot;
    &quot;sync&quot;
    &quot;time&quot;
)

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 + &quot; plus more letters&quot;
    fmt.Println(&quot;Before sleep&quot;)
    random_sleep()
    mutex.Lock()
    defer mutex.Unlock()
    m[word] = added_word
    fmt.Println(&quot;Added word %v&quot;, 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{&quot;cat&quot;, &quot;dog&quot;, &quot;fish&quot;})
    // fmt.Println(result)
}

I have the Python script:

from ctypes import cdll

&quot;&quot;&quot;
run

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

first
&quot;&quot;&quot;

lib = cdll.LoadLibrary(&#39;./try_async.so&#39;)

print(&quot;Loaded go lib&quot;)
result = lib.add_all_items_to_map([&#39;cat&#39;, &#39;dog&#39;, &#39;fish&#39;])
print(result)

The outcome is strange error that others said is when you don't build the shared object, but I did:

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 &quot;go-async-caller.py&quot;, line 14, in &lt;module&gt;
    result = lib.add_all_items_to_map([&#39;cat&#39;, &#39;dog&#39;, &#39;fish&#39;])
  File &quot;/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py&quot;, line 375, in __getattr__
    func = self.__getitem__(name)
  File &quot;/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py&quot;, line 380, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found

The following does work:

libadd.go-

//libadd.go
package main

import &quot;C&quot;

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

func main() {}

go-caller-example.py-

from ctypes import cdll

&quot;&quot;&quot;
run

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

first
&quot;&quot;&quot;

lib = cdll.LoadLibrary(&#39;./libadd.so&#39;)

print(&quot;Loaded go lib&quot;)
result = lib.add(2, 3)
print(result)

like this

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/

答案1

得分: 1

在Go语言中,指令有点脆弱,你需要完全正确地书写它们,否则它们会悄无声息地失败。

在这种情况下,你写成了这样:

// export add_all_items_to_map

但应该写成这样:

//export add_all_items_to_map

请参考cgo文档获取更多信息。

英文:

Directives in Go are kinda fragile, you need to get them exactly right or they will fail silently.

In this case you have this:

// export add_all_items_to_map

But need this:

//export add_all_items_to_map

See the cgo docs for more information.

huangapple
  • 本文由 发表于 2017年7月29日 03:31:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/45381104.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定