英文:
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 (
"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)
}
I have the Python script:
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)
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 "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
The following does work:
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)
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论