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

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

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

问题

我有以下的go文件:

  1. //try_async.go
  2. package main
  3. import (
  4. "C"
  5. "fmt"
  6. "math/rand"
  7. "sync"
  8. "time"
  9. )
  10. var mutex sync.Mutex
  11. var wg sync.WaitGroup
  12. func random_sleep() {
  13. r := rand.Intn(3000)
  14. time.Sleep(time.Duration(r) * time.Millisecond)
  15. }
  16. func add_to_map(m map[string] string, word string) {
  17. defer wg.Done()
  18. added_word := word + " plus more letters"
  19. fmt.Println("Before sleep")
  20. random_sleep()
  21. mutex.Lock()
  22. defer mutex.Unlock()
  23. m[word] = added_word
  24. fmt.Println("Added word %v", word)
  25. }
  26. // export add_all_items_to_map
  27. func add_all_items_to_map(words []string) map[string]string {
  28. words_map := make(map[string]string)
  29. for _, this_word := range words {
  30. wg.Add(1)
  31. go add_to_map(words_map, this_word)
  32. }
  33. wg.Wait()
  34. return words_map
  35. }
  36. func main() {
  37. // result := add_all_items_to_map([]string{"cat", "dog", "fish"})
  38. // fmt.Println(result)
  39. }

我有以下的Python脚本:

  1. from ctypes import cdll
  2. """
  3. run
  4. go build -buildmode=c-shared -o try_async.so try_async.go
  5. first
  6. """
  7. lib = cdll.LoadLibrary('./try_async.so')
  8. print("Loaded go lib")
  9. result = lib.add_all_items_to_map(['cat', 'dog', 'fish'])
  10. print(result)

结果是一个奇怪的错误,其他人说这是因为你没有构建共享对象,但我已经构建了:

  1. cchilders:~/work_projects/golang_integration (feature/golang-query)
  2. $ rm *.so
  3. cchilders:~/work_projects/golang_integration (feature/golang-query)
  4. $ go build -buildmode=c-shared -o try_async.so try_async.go
  5. cchilders:~/work_projects/golang_integration (feature/golang-query)
  6. $ python go-async-caller.py
  7. Loaded go lib
  8. Traceback (most recent call last):
  9. File "go-async-caller.py", line 14, in <module>
  10. result = lib.add_all_items_to_map(['cat', 'dog', 'fish'])
  11. File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 375, in __getattr__
  12. func = self.__getitem__(name)
  13. File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 380, in __getitem__
  14. func = self._FuncPtr((name_or_ordinal, self))
  15. AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found

以下是可以工作的代码示例:

libadd.go-

  1. //libadd.go
  2. package main
  3. import "C"
  4. //export add
  5. func add(left int, right int) int {
  6. return left + right
  7. }
  8. func main() {}

go-caller-example.py-

  1. from ctypes import cdll
  2. """
  3. run
  4. go build -buildmode=c-shared -o libadd.so libadd.go
  5. first
  6. """
  7. lib = cdll.LoadLibrary('./libadd.so')
  8. print("Loaded go lib")
  9. result = lib.add(2, 3)
  10. print(result)

像这样:

  1. cchilders:~/work_projects/golang_integration (feature/golang-query)
  2. $ go build -buildmode=c-shared -o libadd.so libadd.go
  3. cchilders:~/work_projects/golang_integration (feature/golang-query)
  4. $ python go-caller-example.py
  5. Loaded go lib
  6. 5

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

英文:

I have the following go file:

  1. //try_async.go
  2. package main
  3. import (
  4. &quot;C&quot;
  5. &quot;fmt&quot;
  6. &quot;math/rand&quot;
  7. &quot;sync&quot;
  8. &quot;time&quot;
  9. )
  10. var mutex sync.Mutex
  11. var wg sync.WaitGroup
  12. func random_sleep() {
  13. r := rand.Intn(3000)
  14. time.Sleep(time.Duration(r) * time.Millisecond)
  15. }
  16. func add_to_map(m map[string] string, word string) {
  17. defer wg.Done()
  18. added_word := word + &quot; plus more letters&quot;
  19. fmt.Println(&quot;Before sleep&quot;)
  20. random_sleep()
  21. mutex.Lock()
  22. defer mutex.Unlock()
  23. m[word] = added_word
  24. fmt.Println(&quot;Added word %v&quot;, word)
  25. }
  26. // export add_all_items_to_map
  27. func add_all_items_to_map(words []string) map[string]string {
  28. words_map := make(map[string]string)
  29. for _, this_word := range words {
  30. wg.Add(1)
  31. go add_to_map(words_map, this_word)
  32. }
  33. wg.Wait()
  34. return words_map
  35. }
  36. func main() {
  37. // result := add_all_items_to_map([]string{&quot;cat&quot;, &quot;dog&quot;, &quot;fish&quot;})
  38. // fmt.Println(result)
  39. }

I have the Python script:

  1. from ctypes import cdll
  2. &quot;&quot;&quot;
  3. run
  4. go build -buildmode=c-shared -o try_async.so try_async.go
  5. first
  6. &quot;&quot;&quot;
  7. lib = cdll.LoadLibrary(&#39;./try_async.so&#39;)
  8. print(&quot;Loaded go lib&quot;)
  9. result = lib.add_all_items_to_map([&#39;cat&#39;, &#39;dog&#39;, &#39;fish&#39;])
  10. print(result)

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

  1. cchilders:~/work_projects/golang_integration (feature/golang-query)
  2. $ rm *.so
  3. cchilders:~/work_projects/golang_integration (feature/golang-query)
  4. $ go build -buildmode=c-shared -o try_async.so try_async.go
  5. cchilders:~/work_projects/golang_integration (feature/golang-query)
  6. $ python go-async-caller.py
  7. Loaded go lib
  8. Traceback (most recent call last):
  9. File &quot;go-async-caller.py&quot;, line 14, in &lt;module&gt;
  10. result = lib.add_all_items_to_map([&#39;cat&#39;, &#39;dog&#39;, &#39;fish&#39;])
  11. 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__
  12. func = self.__getitem__(name)
  13. 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__
  14. func = self._FuncPtr((name_or_ordinal, self))
  15. AttributeError: dlsym(0x7fc4cfd563b0, add_all_items_to_map): symbol not found

The following does work:

libadd.go-

  1. //libadd.go
  2. package main
  3. import &quot;C&quot;
  4. //export add
  5. func add(left int, right int) int {
  6. return left + right
  7. }
  8. func main() {}

go-caller-example.py-

  1. from ctypes import cdll
  2. &quot;&quot;&quot;
  3. run
  4. go build -buildmode=c-shared -o libadd.so libadd.go
  5. first
  6. &quot;&quot;&quot;
  7. lib = cdll.LoadLibrary(&#39;./libadd.so&#39;)
  8. print(&quot;Loaded go lib&quot;)
  9. result = lib.add(2, 3)
  10. print(result)

like this

  1. cchilders:~/work_projects/golang_integration (feature/golang-query)
  2. $ go build -buildmode=c-shared -o libadd.so libadd.go
  3. cchilders:~/work_projects/golang_integration (feature/golang-query)
  4. $ python go-caller-example.py
  5. Loaded go lib
  6. 5

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

答案1

得分: 1

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

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

  1. // export add_all_items_to_map

但应该写成这样:

  1. //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:

  1. // export add_all_items_to_map

But need this:

  1. //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:

确定