描述发生了什么:
就上下文而言,我目前正在尝试将 python 嵌入到 golang 中。我遇到了这个模块 go-python3
并决定使用它。我最初使用该模块的 python3.7 变体,然后决定将我的 python 版本从 3.7 升级到 3.8。
阅读:https://github.com/go-python/cpy3/issues/29#issuecomment-1321199010
我将 pkgconfig
中的 python3.pc 替换为 python-3.8.pc
,并在尝试运行时出现以下错误:
protoc -isrc/proto --go_opt=module=grpc-golang --go_out=. --go-grpc_opt=module=grpc-golang --go-grpc_out=. src/proto/*.proto go build -o dest/server ./src/server && pythonpath=. # grpc-golang/src/server /usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1 /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x78): undefined reference to `pybool_type' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x80): undefined reference to `pybytearray_type' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x88): undefined reference to `pybytes_type' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x90): undefined reference to `pycomplex_type' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0x98): undefined reference to `pydict_type' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa0): undefined reference to `pyexc_arithmeticerror' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xa8): undefined reference to `pyexc_assertionerror' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb0): undefined reference to `pyexc_attributeerror' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xb8): undefined reference to `pyexc_baseexception' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc0): undefined reference to `pyexc_blockingioerror' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xc8): undefined reference to `pyexc_brokenpipeerror' /usr/bin/ld: /tmp/go-link-2733155445/go.o:(.data+0xd0): undefined reference to `pyexc_buffererror' :
这是一些细节:
>> python3 --version 3.8.10 >> pkg-config --cflags --libs python3 -I/usr/include/python3.8 -I/usr/include/x86_64-linux-gnu/python3.8 >> echo $PKG_CONFIG_PATH /usr/lib/x86_64-linux-gnu/pkgconfig/ >> pkg-config --list-all python-3.8 Python - Build a C extension for Python zlib zlib - zlib compression library protobuf-lite Protocol Buffers - Google's Data Interchange Format bash-completion bash-completion - programmable completion for the bash shell xkeyboard-config XKeyboardConfig - X Keyboard configuration data protobuf Protocol Buffers - Google's Data Interchange Format systemd systemd - systemd System and Service Manager libdmmp libdmmp - Device mapper multipath management library python3 Python - Build a C extension for Python libxcrypt libxcrypt - Extended crypt library for DES, MD5, Blowfish and others udev udev - udev shared-mime-info shared-mime-info - Freedesktop common MIME database python-3.8-embed Python - Embed Python into an application expat expat - expat XML parser python3-embed Python - Embed Python into an application libcrypt libxcrypt - Extended crypt library for DES, MD5, Blowfish and others
描述您的期望: 应该能够正常工作,就像它的 3.7 版本一样。
我最近遇到了类似的问题。在搜索了一些关于嵌入 python 的论坛后,我遇到了这个:“在 c 中嵌入 python,链接失败,未定义对‘py_initialize’的引用”1。一开始我并不完全确定如何在 golang 中执行此操作,但我一直在对 golang 中的嵌入式 python 进行其他在线搜索。回顾这些,我找到了一篇文章,“python 和 go:第四部分 - 在内存中使用 python”2,其中在“构建”部分描述了如何指定在 c 构建过程中使用的特定标志。基本上,它表明您可以在其中一个文件中定义标志,如下所示:
/* #cgo pkg-config: python3 #cgo ldflags: -l/usr/local/lib/python3.8/config-3.8-x86_64-linux-gnu -l/usr/local/lib -lpython3.8 -lcrypt -ldl -lm -lm #include "python.h" */ import "c"
尽管根据 python 的有关编译嵌入到另一个应用程序中的 python 解释器的文档,您应该通过以下方式获取 ldflags,
python3.7-config --ldflags
对于 python 版本 <= 3.7 (我不知道 if 回溯到多远。另外,相应地替换“python3.7-config”),或者,
python3.10-config --ldflags --embed
对于 python 版本 > 3.7(再次将“python3.10-config”部分替换为所需的 python 版本)
然后我心里想,“这个头文件的一个版本可能位于 go-python 项目中的某个地方,只需要更改它”,所以环顾四周后,我在 high_level_layer.go 文件中找到了这个头文件该项目并对其进行了修改以匹配上面显示的内容。
这里到底发生了什么,golang 具有 c 的原生功能,因此用 c 编写的库可以在 golang 中工作,反之亦然(有足够的欺骗)。有很多关于此功能的文章。这是来自 go 官方网站的一个,3。由于基本的 python 解释器是用 c 编写的,如果链接器标志和其他标志设置正确,则 golang 编译器可以在编译时引用其头文件和目标文件,这正是上面指定的内容。
此外,另一方面,我尝试使用一些不同的 go 编译器进行编译。我在 1.15.5 和 1.18.1 版本的编译器上取得了成功,但在 1.19.5 版本上却没有成功。我不知道到底发生了什么,但我现在不会尝试弄清楚它,因为我当前需要的只是编译器版本 >= 1.18 中的功能。最后,我实际上在 python3.7 中遇到了基本相同的问题,这些更改也解决了这些问题...