g++如何结合python.h进行编译?

9

我使用g++编译了一个测试代码,没有遇到任何问题。

#include "Python.h"  

int main(int argc, char** argv)  
{  
    Py_Initialize();  
    PyRun_SimpleString("import pylab");  
    PyRun_SimpleString("pylab.plot(range(5))");  
    PyRun_SimpleString("pylab.show()");  
    Py_Exit(0);  
} 

g++ -o test test.cpp -I/usr/include/python2.7/ -lpython2.7

这段代码可以正常工作并运行。

但是当我试图将这段代码嵌入到另一个项目中时,它失败了。这真的让我很困惑。

Makefile如下所示。

CXX=g++  
CXXFLAGS=-DIB_USE_STD_STRING -Wall -Wno-switch -g  
ROOT_DIR=..  
BASE_SRC_DIR=${ROOT_DIR}/PosixSocketClient  
INCLUDES=-I${ROOT_DIR}/Shared/ -I${BASE_SRC_DIR} -I/usr/include/python2.7  
LIBRARY=-L/usr/lib/python2.7/config  
TARGET=eu  

$(TARGET):  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o EClientSocketBase.o -c   $(BASE_SRC_DIR)/EClientSocketBase.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o EPosixClientSocket.o -c   $(BASE_SRC_DIR)/EPosixClientSocket.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o PosixTestClient.o -c PosixTestClient.cpp  
    $(CXX) $(CXXFLAGS) $(INCLUDES) -o Main.o -c Main.cpp
    $(CXX) $(LIBRARY) -lpython2.7 -o $@ EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o 

clean:  
    rm -f $(TARGET) *.o  

这个项目编译和运行都很好,我唯一做的改变就是在Main.cpp文件中添加了测试代码。警告/错误消息如下所示:

来自/usr/include/python2.7/Python.h:8:0的文件包含,
来自Main.cpp:15:
/usr/include/python2.7/pyconfig.h:1158:0: 警告:"_POSIX_C_SOURCE"被重新定义[默认启用]
/usr/include/features.h:163:0: 注意:这是以前定义的位置
/usr/include/python2.7/pyconfig.h:1180:0: 警告:"_XOPEN_SOURCE"被重新定义[默认启用]
/usr/include/features.h:165:0: 注意:这是以前定义的位置
g++ -L/usr/lib/ -lpython2.7 -ldl -lutil -o eu EClientSocketBase.o EPosixClientSocket.o PosixTestClient.o Main.o
Main.o: 在函数 main' 中:
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:81: 对`Py_Initialize'未定义的引用
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:82: 对`PyRun_SimpleStringFlags'未定义的引用
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:83: 对`PyRun_SimpleStringFlags'未定义的引用
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:84: 对`PyRun_SimpleStringFlags'未定义的引用
/home/bbc/TWS/IBJts/cpp/eu-ats/Main.cpp:85: 对`Py_Exit'未定义的引用
collect2: ld 返回了 1 个退出状态
make: * [eu] 错误 1

需要帮助吗?谢谢!

2
也许lib python是一个“普通”的C库,因此您可能需要使用external "C" { .. }来确保C的“链接”(实际上,.h文件自己检查是否在C或C++编译器下运行...)。 - ShinTakezou
尝试运行 nm libpython2.7.so | grep Py_Initialize 命令,查看该符号是否在库中。 - selalerer
你在 main.cpp 中添加了几行代码,结果出现了多个错误。尝试恢复到旧版本,验证其是否正常工作,然后只添加 #include "Python.h" 这一行,看看会发生什么。我敢打赌你会得到“重定义”的错误,但不会得到“未定义”的错误,这意味着你可能忘记在某个头文件中加入头文件保护。一旦这个问题解决了,我们就可以解决“未定义”的错误,这些错误可能来自于未能链接对象文件(如 Python.o)。 - Beta
2
已经解决了,Makefile中真正的问题是参数的顺序,我之前不知道顺序很重要(在一行中的顺序)。 - bbc
7
要消除 _POSIX_C_SOURCE 警告,请确保首先包含 Python.h - Lucas
2个回答

16
请看Lucas的评论:

“为了消除_POSIX_C_SOURCE警告,请确保在所有其他头文件之前包含Python.h。”

我也遇到了同样的问题。 我使用Boost Python,因此对于我来说,我将boost / python.hpp的包含移动到了我的.cpp文件的第一行。

(Lukas,请将您的评论发布为答案,以便提问者可以将其标记为正确答案,问题将不会在StackOverflow上保持“未回答”。)


0

这是Python中的一个错误:https://bugs.python.org/issue1045893

如果您首先包含Python.h,编译器不会抱怨,但是当定义_GNU_SOURCE时,GNU libc的/usr/include/features.h将覆盖它:

#undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #undef _XOPEN_SOURCE #define _XOPEN_SOURCE 700


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接