Python调用golang编译的.so库报“dlsym(0x7fe2a7d4ea30, background): symbol not found”错误的原因是什么?
- golang 代码:
package main
import (
“C”
“github.com/360EntSecGroup-Skylar/excelize”
)
func background(excelname, sheetname, image *C.char) *C.char {
excelname_go := C.GoString(excelname)
sheetname_go := C.GoString(sheetname)
image_go := C.GoString(image)
xlsx, err := excelize.OpenFile(excelname_go)
if err != nil {
panic(err)
}
xlsx.SetSheetBackground(sheetname_go, image_go)
err = xlsx.SaveAs(excelname_go)
if err != nil {
panic(err)
}
return C.CString("success")
}
func main() {}
import ctypes
from ctypes import cdll
def set_background():
name = b’/Users/myyou/work/background.xlsx’
background = cdll.LoadLibrary(’/Users/myyou/work/excel.so’).background
background.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
background.restype = ctypes.c_char_p
background(name, b’Sheet1’, b’/Users/myyou/work/ntim.jpg’)
return ‘ok’
- 调用后发生的错误:
Traceback (most recent call last):
File "/Users/myyou/work/pythonenv/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-3-24964e319282>", line 1, in <module>
set_background()
File "/Users/myyou/work/test.py", line 275, in
background = cdll.LoadLibrary('/Users/kamui/work/excel.so').background
File "/Users/myyou/.pyenv/versions/3.6.2/lib/python3.6/ctypes/__init__.py", line 361, in __getattr__
func = self.__getitem__(name)
File "/Users/myyou/.pyenv/versions/3.6.2/lib/python3.6/ctypes/__init__.py", line 366, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: dlsym(0x7fe2a7d4ea30, background): symbol not found
Python调用golang编译的.so库报“dlsym(0x7fe2a7d4ea30, background): symbol not found”错误的原因是什么?
更多关于Python调用golang编译的.so库报“dlsym(0x7fe2a7d4ea30, background): symbol not found”错误的原因是什么?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这个错误通常是因为Go的C导出函数命名规则导致的。Go编译器会对C导出函数名进行名称修饰(name mangling),而你在Python中调用时使用了错误的函数名。
根本原因:
Go编译器在编译共享库时,会为C导出函数添加前缀(通常是包名)并修改大小写。比如你定义的background函数,实际在.so文件中可能被命名为main.background或_cgoexp_开头的名称。
解决方案:
- 查看实际符号名:
nm -D yourlib.so | grep background
- 正确的Go代码示例(需显式导出):
// main.go
package main
import "C"
//export Background
func Background() {
// 你的函数实现
}
func main() {}
- 编译命令:
go build -buildmode=c-shared -o yourlib.so main.go
- Python调用代码:
from ctypes import CDLL
lib = CDLL('./yourlib.so')
# 使用实际导出的函数名,通常是"Background"(注意大小写)
lib.Background()
关键点:
- 必须使用
//export 函数名注释 - 函数名首字母必须大写
- 编译时必须指定
-buildmode=c-shared
一句话总结:检查Go导出的实际符号名并在Python中使用正确名称。
更多关于Python调用golang编译的.so库报“dlsym(0x7fe2a7d4ea30, background): symbol not found”错误的原因是什么?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
- 自己找到原因了,需要价格注释
<br>import ctypes<br>from ctypes import cdll<br><br>//export background<br>def set_background():<br> name = b'/Users/myyou/work/background.xlsx'<br> background = cdll.LoadLibrary('/Users/myyou/work/<a target="_blank" href="http://excel.so" rel="nofollow noopener">excel.so</a>').background<br> background.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]<br> background.restype = ctypes.c_char_p<br> background(name, b'Sheet1', b'/Users/myyou/work/ntim.jpg')<br> return 'ok'<br>
注释加错了,应该加载 golang 代码中<br>package main<br><br>import (<br> "C"<br> "<a target="_blank" href="http://github.com/360EntSecGroup-Skylar/excelize" rel="nofollow noopener">github.com/360EntSecGroup-Skylar/excelize</a>"<br> )<br><br>//export background<br>func background(excelname, sheetname, image *C.char) *C.char {<br> excelname_go := C.GoString(excelname)<br> sheetname_go := C.GoString(sheetname)<br> image_go := C.GoString(image)<br><br> xlsx, err := excelize.OpenFile(excelname_go)<br> if err != nil {<br> panic(err)<br> }<br> <br> xlsx.SetSheetBackground(sheetname_go, image_go)<br><br> err = xlsx.SaveAs(excelname_go)<br> if err != nil {<br> panic(err)<br> }<br><br> return C.CString("success")<br>}<br><br>func main() {}<br><br>

