今天在开例会的时候,提到其他小组要做一个通用任务系统,会涉及到C++调用其他语言脚本开发的逻辑。之前倒是听互娱那边的同事说过,他们都是嵌入lua来进行脚本编程,但自己从来没试过。
而作为一个严重中毒的vim+python爱好者,其实我每天都在用vim直接执行python命令(如出名的pyflakes插件),想知道vim是怎么实现的,所以就自己试了一下。
由于家里没有linux开发环境,所以就在windows下用 Mingw + makefile的方式开发了。
先写一个简单的py程序:helloworld.py
def hello():
print"hello,world!"
然后来写我们的c++代码:
py.cpp
#include<Python.h>//前面所做的一切配置都是为了调用这个头文件和相关库
int main()
{
Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject * pModule = NULL;//声明变量
PyObject * pFunc = NULL;// 声明变量
pModule =PyImport_ImportModule("helloworld");//这里是要调用的文件名
pFunc= PyObject_GetAttrString(pModule, "hello");//这里是要调用的函数名
PyEval_CallObject(pFunc, NULL);//调用函数
Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。
return 0;
}
然后是makefile:
CXX = g++
TARGET = py
C_FLAGS += -g -Wall
INC = -IC:/Python27/include/
LIB = -LC:/Python27/libs/ -lpython27
all: $(TARGET)
py: py.o
$(CXX) -o $@ $^ $(LIB) $(C_FLAGS)
.cpp.o:
$(CXX) -c -o $*.o $(INC) $(C_FLAGS) $*.cpp
clean:
-rm -f *.o $(TARGET)
执行结果如下:
C:\WINDOWS\system32\cmd.exe /c py
hello,world!
目前只是简单研究了一下,等到以后需要用到的时候再深入吧。
代码路径:http://code.google.com/p/vimercode/source/browse/#svn/trunk/cpppy
另网上有几篇比较详细的文章,有兴趣的朋友可以看一下。
C++调用Python(3)
C++调用Python(4)
-------------------------------------------------------------------
linux下的makefile如下:
CXX = g++
TARGET = test_py
C_FLAGS += -g -Wall -pthread
INC = -I/usr/local/include/python2.7/
LIB = -L/usr/local/lib/ -lpython2.7 -ldl -lutil
all: $(TARGET)
test_py: test_py.o
$(CXX) -o $@ $^ $(LIB) $(C_FLAGS)
.cpp.o:
$(CXX) -c -o $*.o $(INC) $(C_FLAGS) $*.cpp
clean:
-rm -f *.o $(TARGET)
此程序在linux下运行会core,可以尝试看一下这篇文章: http://blog.csdn.net/marising/archive/2008/09/12/2917892.aspx
iCyOMiK on #
谢,收下了。
Reply
iCyOMiK on #
Segmentation fault
怎么搞?我只是Makefile里面的:
INC = -I/usr/include/python2.6/
LIB = -L/usr/lib/python2.6/ -lpython2.6
和你不同而已,不明白怎么是段错误。。。
Reply
Dante on #
gdb调试一下,看一下core在哪里~~
Reply
iCyOMiK on #
Program received signal SIGSEGV, Segmentation fault.
0x001a2100 in PyObject_GetAttrString () from /usr/lib/libpython2.6.so.1.0
Reply
Dante on #
奇怪了。。我这里没报错。。你检查看是不是细节上出问题了?
Reply
iCyOMiK on #
我除了Makefile是复制你的,其它两个文件都是手打的,都不明白怎么会这样呢。。。难道是
INC = -I/usr/include/python2.6/
LIB = -L/usr/lib/python2.6/ -lpython2.6
的问题么???
Reply
Dante on #
额,你的makefile应该是没问题的~
有没有试过直接用我的代码呢?
Reply
iCyOMiK on #
嗯,当然,是因为直接复制你的代码make后出现上面我说情况,所以我才手打一次的,我用下面的方法make的:
~/project-tmp/cpp+py $ make
g++ -c -o py.o -I /usr/include/python2.6/ -g -Wall py.cpp
g++ -o py py.o -L /usr/lib/python2.6/ -l python2.6 -g -Wall
~/project-tmp/cpp+py $ ./py
Segmentation fault
Reply
lihex on #
我的同样是段错误:
lihex@lihex-laptop:/tmp$ make
g++ -c -o py.o -I/usr/include/python2.6/ -g -Wall py.cpp
g++ -o py py.o -L/usr/lib/ -lpython2.6 -g -Wall
lihex@lihex-laptop:/tmp$ ./py
段错误
lihex@lihex-laptop:/tmp$
Reply
iCyOMiK on #
版本:
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
Reply
iCyOMiK on #
呃。。。有没有是python2.7的可能?
Reply
Dante on #
呃,我觉得应该不会和python2.7有关。。
可能是linux编译参数的问题?这个我得周一到公司试一下~
Reply
iCyOMiK on #
嗯,谢谢你吖,太麻烦你了,不过说真的,我觉得不同语言之间能相互调用实在太酷了。
Reply
Dante on #
我刚在ubuntu虚拟机上编译了一下,python2.7,
INC = -I /usr/local/include/python2.7/
LIB = -L /usr/local/lib/ -lpython2.7 -L/usr/lib/ -lssl -lcrypto
编译会失败,应该是有一些包没装,我找时间看一下~
Reply
Dante on #
原因找到了,要加入这两行
Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
Reply
iCyOMiK on #
呃,之前还以为你把这件事情忘记了呢~呵呵,我去试试~真的很感谢你的贡献~相信很多人看到后都会获益的,要不你修改一下原文,把它加上去吧~
Reply
iCyOMiK on #
呃,原来你已经加上去了~呵呵~测试成功,感谢,迟些再把该文章转走,放心,我会留原文链接的哈!!
Reply
Dante on #
有用就好,哈哈~~最近在继续深入研究这一块,还是发现了不少问题的~以后会继续写几篇文章总结~
Reply
sly on #
我的代码和你的一样,Makefile,也一样
就是编译不过去,总是提示我Py_Initialize() 函数未定义,头文件 #include
Reply
Ding_yan333 on #
赞
Reply
Bruce on #
看到这里才debug好,感谢感谢!
Reply