什么是未定义的参考/未解决的外部符号错误?什么是常见原因以及如何修复/预防它们?
随意编辑/添加您自己的.
c++ c++-faq linker-errors unresolved-external undefined-reference
在下面的代码的第二次调用,我的应用程序段错误,所以我想我错过了一些东西:
Py_Initialize();
pName = PyString_FromString("comp_macbeth");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule == NULL) {
PyErr_Print();
Py_Finalize();
return;
}
pFunc = PyObject_GetAttrString(pModule, "compute");
/* pFunc is a new reference */
if (!pFunc || !PyCallable_Check(pFunc) ) {
PyErr_Print();
Py_Finalize();
return;
}
Py_Finalize();
Run Code Online (Sandbox Code Playgroud)
comp_macb.py正在导入numpy.如果我删除numpy导入,一切都很好.这是一个numpy bug,还是我错过了一些关于进口的东西?
我无法获得已编译的 python 脚本所看到的其他可用模块。我需要如何更改以下流程才能接受基于 venv 的模块或全局模块?
脚步:
$ python3 -m venv sometest
$ cd sometest
$ . bin/activate
(sometest) $ pip3 install PyCrypto Cython
Run Code Online (Sandbox Code Playgroud)
使用非标准模块的基本脚本Crypto:
# hello.py
from Crypto.Cipher import AES
import base64
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
msg = "The answer is no"
ciphertext = obj.encrypt(msg)
print(msg)
print(base64.b64encode(ciphertext))
Run Code Online (Sandbox Code Playgroud)
(sometest) $ python3 hello.py
The answer is no
b'1oONZCFWVJKqYEEF4JuL8Q=='
Run Code Online (Sandbox Code Playgroud)
编译它:
(sometest) $ cython -3 --embed hello.py
(sometest) $ gcc -Os -I /usr/include/python3.5m -o hello …Run Code Online (Sandbox Code Playgroud) 我正在尝试从 python 源文件创建一个 unix 可执行文件。
我有两个文件,p1.py并且p2.py
p1.py:-
from p2 import test_func
print (test_func())
Run Code Online (Sandbox Code Playgroud)
p2.py:-
def test_func():
return ('Test')
Run Code Online (Sandbox Code Playgroud)
现在,正如我们所看到的,p1.py依赖于p2.py. 我想通过将两个文件组合在一起来制作一个可执行文件。我正在使用 cython。
我将文件名分别更改为p1.pyx和p2.pyx。
现在,我可以使用 cython 使文件可执行,
cython p1.pyx --embed
Run Code Online (Sandbox Code Playgroud)
它将生成一个名为 .c 的 C 源文件p1.c。接下来我们可以使用 gcc 使其可执行,
gcc -Os -I /usr/include/python3.5m -o test p1.c -lpython3.5m -lpthread -lm -lutil -ldl
Run Code Online (Sandbox Code Playgroud)
但是如何将两个文件合并为一个可执行文件呢?
我正在尝试在C程序中调用cython(cdef)函数。当cdef函数包含python语句(例如print(0.5)或python(def)函数)时,调用(cdef)函数会引发分段错误。
.pyx文件:
# cython: language_level=3
cdef public double PI = 3.1415926
cdef public double get_e():
print("calling get_e()")
return 2.718281828
Run Code Online (Sandbox Code Playgroud)
.c文件:
#include "Python.h"
#include "transcendentals.h"
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
Py_Initialize();
PyInit_transcendentals();
printf("pi**e: %f\n", pow(PI, get_e()));
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译命令:
cython transcendentals.pyx
gcc -I. -I/usr/include/python3.5m -I/usr/include/python3.5m \
-Wno-unused-result -Wsign-compare \
-g -fstack-protector-strong -Wformat \
-Werror=format-security -DNDEBUG -g \
-fwrapv -O3 -Wall -Wstrict-prototypes \
-L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu \
-L/usr/lib transcendentals.c main.c \
-lpython3.5m -lpthread -ldl -lutil -lm -Xlinker …Run Code Online (Sandbox Code Playgroud) TL;DR:如何使用 Cython 作为分发方法而不是 Py2exe、cx_freeze、pyinstaller 等。
继在用Cython制作一个可执行的,我想看看它怎么可能给一个Python程序分发到任何Windows用户(谁没有的Python已经安装了机上),通过用Cython第一编译它--embed。
让我们使用一个test.py:
import json
print(json.dumps({'key': 'hello world'}))
Run Code Online (Sandbox Code Playgroud)
并编译它:
cython test.py --embed
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
cl test.c /I C:\Python37\include /link C:\Python37\libs\python37.lib
Run Code Online (Sandbox Code Playgroud)
它可以工作并生成一个 140KB 的test.exe可执行文件。
test.exe在另一台机器上运行不能开箱即用,它需要:
即使这样,它仍然不起作用(下面的屏幕截图而不是复制/粘贴,因为我没有管理 VM 中的复制/粘贴 - 此处偏离主题):
ModuleNotFoundError:没有名为“编码”的模块
问题:分发--embed-Cython 编译的代码并使其在任何机器上运行(之前没有安装 Python)所需的最小文件集是什么?
如果我在 Windows 上从源代码构建 CPython,当我想要 pip 安装包含 C 扩展的包时,我会遇到问题。链接库时似乎发生了错误。
例如,安装 cython 时(但在其他 C 扩展包上也会崩溃并出现相同的错误):
链接:致命错误 LNK1104:无法打开文件“python38.lib”
错误:命令“C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\link.exe”失败,退出状态为 1104
之所以无法打开“python38.lib”,是因为调试模式下的“.lib”文件名为“python38_d.lib”。
一个最小的可重现示例(在命令行上)基于CPython 开发人员指南的快速参考:
git clone --branch v3.8.0 https://github.com/python/cpython.git
cd cpython
git checkout v3.8.0
.\PCbuild\build.bat -e -d
.\PCbuild\win32\python_d.exe -m ensurepip
.\PCbuild\win32\python_d.exe -m pip install pip --upgrade -vv
.\PCbuild\win32\python_d.exe -m pip install setuptools --upgrade -vv
.\PCbuild\win32\python_d.exe -m pip install cython -vv
Run Code Online (Sandbox Code Playgroud)
结果distutils.sysconfig.get_config_vars()是:
{'BINDIR': '...\\cpython\\PCbuild\\win32',
'BINLIBDEST': ...\\cpython\\Lib',
'EXE': '.exe',
'EXT_SUFFIX': '_d.cp38-win32.pyd',
'INCLUDEPY': '...\\cpython\\include;...\\cpython\\PC',
'LIBDEST': '...\\cpython\\Lib',
'SO': '_d.cp38-win32.pyd',
'VERSION': …Run Code Online (Sandbox Code Playgroud) 根据文档,可以使用从 Cython 生成的 C 头文件。我已经Hello World毫无问题地遵循了这个例子,现在我想尝试一些不同的东西。我想使用公共声明来使用自定义方法。我的代码结构如下:
你好.pyx
cdef public void say_hello():
print("Hello World")
Run Code Online (Sandbox Code Playgroud)
设置文件
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("hello", ["hello.pyx", "main.c"]),
]
setup(
name='Hello app',
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules
)
Run Code Online (Sandbox Code Playgroud)
主文件
#include "hello.h"
int main(void){
say_hello();
}
Run Code Online (Sandbox Code Playgroud)
在main.c作为测试文件以验证该say_hello()方法按预期工作。构建安装文件python3 setup.py build_ext会产生以下输出。
running build_ext
skipping 'hello.c' Cython extension (up-to-date)
building 'hello' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall …Run Code Online (Sandbox Code Playgroud) cython ×5
python ×5
c ×3
c++ ×1
c++-faq ×1
compilation ×1
cpython ×1
cx-freeze ×1
cythonize ×1
module ×1
numpy ×1
pip ×1
python-3.x ×1
python-c-api ×1
setuptools ×1
windows ×1