剧透警告:已部分解决(请查看结尾)。
以下是使用Python嵌入的代码示例:
#include <Python.h>
int main(int argc, char** argv)
{
Py_SetPythonHome(argv[1]);
Py_Initialize();
PyRun_SimpleString("print \"Hello !\"");
Py_Finalize();
return 0;
}
我在Linux openSUSE 42.2下使用gcc 4.8.5工作(但是我在使用gcc 4.8.3的openSUSE 13.2或者gcc 4.4.7的RedHat 6.4系统中也遇到了同样的问题)。
我编译了Python 2.7.9的动态和静态版本(但是我在使用Python 2.7.13时也遇到了同样的问题)。
我使用以下命令将我的示例链接到Python的静态版本:
g++ hello.cpp -o hello \
-I /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/include/python2.7 \
-L /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/lib \
-l python2.7 -l pthread -l util -l dl
如果我使用静态版本的Python来执行我的示例,它可以正常工作。
如果我使用动态版本的Python来执行它,我会得到以下错误(它发生在Py_Initialize()
中):
> ./hello /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/dynamic
Fatal Python error: PyThreadState_Get: no current thread
Aborted (core dumped)
我不知道为什么静态版本可以工作而动态版本不能。我该如何解决这种问题?
编辑:我安装Python的脚本如下:
#!/bin/bash
WORKDIR=/home/caduchon/tmp/install_python_2_7_13
ARCHIVEDIR=/home/caduchon/downloads/python
PYTHON_VERSION='2.7.13'
EZ_SETUP_VERSION='0.9'
SETUPTOOLS_VERSION='34.1.0'
CYTHON_VERSION='0.25.2'
NUMPY_VERSION='1.12.0'
SCIPY_VERSION='0.18.1'
MATPLOTLIB_VERSION='2.0.0'
INSTALLDIR=/home/caduchon/softs/python/$PYTHON_VERSION/64/gcc/4.8.5
LAPACKDIR=/home/caduchon/softs/lapack/3.6.1/64/gcc/4.8.5
### Tkinter ###
echo "Install Tkinter"
sudo apt-get install tk-dev
### Workdir ###
echo "Create workdir"
mkdir -p $WORKDIR/static
mkdir -p $WORKDIR/dynamic
### Python
for x in static dynamic
do
echo "Install Python ($x)"
cd $WORKDIR/$x
echo " extract archive"
cp $ARCHIVEDIR/Python-$PYTHON_VERSION.tgz .
tar -xzf ./Python-$PYTHON_VERSION.tgz &> archive.log
cd ./Python-$PYTHON_VERSION
echo " configure"
if [ "$x" = "static" ]
then
./configure --prefix=$INSTALLDIR/$x --libdir=$INSTALLDIR/$x/lib &> configure.log
else
export LD_RUN_PATH=$INSTALLDIR/$x/lib
./configure --enable-shared --prefix=$INSTALLDIR/$x --exec-prefix=$INSTALLDIR/$x --libdir=$INSTALLDIR/$x/lib &> configure.log
fi
echo " build"
make &> make.log
echo " install"
make install &> make_install.log
echo " done"
done
### setuptools
for x in static dynamic
do
echo "Install setuptools ($x)"
cd $WORKDIR/$x
echo " extract archives"
cp $ARCHIVEDIR/ez_setup-$EZ_SETUP_VERSION.tar.gz .
tar -xzf ./ez_setup-$EZ_SETUP_VERSION.tar.gz &> archive.log
cp $ARCHIVEDIR/setuptools-$SETUPTOOLS_VERSION.zip .
unzip ./setuptools-$SETUPTOOLS_VERSION.zip &> archive.log
cp ./ez_setup-$EZ_SETUP_VERSION/ez_setup.py ./setuptools-$SETUPTOOLS_VERSION/.
cd ./setuptools-$SETUPTOOLS_VERSION
echo " install"
$INSTALLDIR/$x/bin/python ./ez_setup.py &> setup.log
echo " done"
done
### Cython
for x in static dynamic
do
echo "Install Cython ($x)"
cd $WORKDIR/$x
echo " extract archive"
cp $ARCHIVEDIR/Cython-$CYTHON_VERSION.tar.gz .
tar -xzf ./Cython-$CYTHON_VERSION.tar.gz &> archive.log
cd ./Cython-$CYTHON_VERSION
echo " install"
$INSTALLDIR/$x/bin/python ./setup.py install &> install.log
echo " done"
done
### NumPy
for x in static dynamic
do
echo "Install NumPy ($x)"
cd $WORKDIR/$x
echo " extract archive"
cp $ARCHIVEDIR/numpy-$NUMPY_VERSION.zip .
unzip ./numpy-$NUMPY_VERSION.zip &> archive.log
cd ./numpy-$NUMPY_VERSION
echo " build"
$INSTALLDIR/$x/bin/python ./setup.py build --fcompiler=gfortran &> build.log
echo " install"
$INSTALLDIR/$x/bin/python ./setup.py install &> install.log
echo " done"
done
### SciPy
for x in static dynamic
do
echo "Install SciPy ($x)"
cd $WORKDIR/$x
echo " extract archive"
cp $ARCHIVEDIR/scipy-$SCIPY_VERSION.tar.gz .
tar -xzf ./scipy-$SCIPY_VERSION.tar.gz &> archive.log
cd ./scipy-$SCIPY_VERSION
echo " configure"
echo "[DEFAULT]" > ./site.cfg
echo "library_dirs = $LAPACKDIR/lib64" >> ./site.cfg
echo "search_static_first = true" >> ./site.cfg
echo " build"
$INSTALLDIR/$x/bin/python ./setup.py build --fcompiler=gfortran &> build.log
echo " install"
$INSTALLDIR/$x/bin/python ./setup.py install &> install.log
echo " done"
done
### MatPlotLib
for x in static dynamic
do
echo "Install MatPlotLib ($x)"
cd $WORKDIR/$x
echo " extract archive"
cp $ARCHIVEDIR/matplotlib-$MATPLOTLIB_VERSION.tar.gz .
tar -xzf ./matplotlib-$MATPLOTLIB_VERSION.tar.gz &> archive.log
cd ./matplotlib-$MATPLOTLIB_VERSION
echo " build"
$INSTALLDIR/$x/bin/python ./setup.py build &> build.log
echo " install"
$INSTALLDIR/$x/bin/python ./setup.py install &> install.log
echo " done"
done
编辑:我找到了问题可能的原因。如果我在动态Python的安装中删除行 export LD_RUN_PATH=$INSTALLDIR/$x/lib
,嵌入式代码就能运行。我通过嵌入式代码打印了sys.path
并且它指向正确的安装路径。但是...这样做我不能直接使用安装:它会加载系统中错误的版本(当我打印sys.path
时,我看到它指向 /usr/...)。另外,我不想设置环境变量来启动Python,因为我在同一台机器上使用多个版本的Python。
编辑:保留我的默认Python安装脚本,通过在编译C++示例时添加选项-rdynamic来解决问题。但我不太明白这个选项是什么,以及会引起哪些问题...
make install
。此外,你能分享一下两个编译版本的_configure_命令(如果设置了任何特定的环境变量:例如_CFLAGS_?或任何其他自定义步骤)吗?通过运行PYTHONHOME=/home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/dynamic /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/bin/python -c "print \"abcd\""
可以复现该问题吗? - CristiFati