C语言中嵌入Python

1.为什么要嵌入python?
这个问题问的好,一般静态语言与脚本语言(不仅仅是python),相互搭配,有两种方式,一种是用c语言写好模块,然后用python去整合,也被称之为扩展python,这样的好处是即有python的灵活性,又有c语言的效率,还有一种就是c语言嵌入python,这样我们就有了一个python解释器了,在游戏编程中常用这种方法,如果你是用静态语言编程,那么修改一些属性,就意为着重新编译,如果程序很大的话,编译是一间令人很烦的事,编译起来非常慢,一种好的设计是把一些属性写在一个初始化文件中,然后在程序中去解析这个属性文件,不过这样还是不够灵活,更加灵活的方式,就是干脆嵌入python(游戏编程中常用lua),这样,游戏更有创造性,更容易扩展。


       2.一个"错误的"例

下面先把C代码写出来,(当然,直接编译肯定是错的,因为我们还有许多东西没设置)

main.c

[cpp] view plain copy print ?
  1. "FONT-SIZE: 14px">  
  2. #include    
  3. int main()  
  4. {  
  5.   
  6. Py_Initialize();  
  7. PyRun_SimpleString("print 'hello,python!'");  
  8. Py_Finalize();  
  9.   
  10. return 0;  
  11. }  
  12.    

#include 
int main()
{

Py_Initialize();
PyRun_SimpleString("print 'hello,python!'");
Py_Finalize();

return 0;
}
 

        Py_Initialize()和Py_Finalize()就是初始化和结束python解释器,PyRun_SimpleString()就在运行一段python语句,(好像表达式不行...)

你一定觉得你没有Python.h这个头文件,所以你不得不安装一个叫python-dev的东西,直接sudo apt-get python-dev好了
现在我们试着编译一下,
gcc -o main.c main
编译错误,它找不到Python.h,它当然找不到,我们虽然已经下载安装了,但是gcc并不能找到,我们需要告诉它,这就要用到gcc 的 -I选项
"-I 在头文件的搜索路径列表中添加dir目录。" --- man 关于gcc -I选项的说明
我们继续尝试编译:
gcc -I/usr/include/python2.6 main.c -o main
然后你会看到一大堆的错误
undefined reference to
恩,链接错误,他们并没有找到库的实现
你需要这样编译
gcc -I/usr/include/python2.6 -lpython2.6 main.c -o main
这次就没问题了。


        实际上我们更常见的做法是写一个python模块,然后导入,调用它,
看这个代码:
Test.py


[python] view plain copy print ?
  1. "FONT-SIZE: 14px">  
  2. def hello():  
  3.     print "nihao"  
  4.   
  5.   

def hello():
    print "nihao"

main.c

[cpp] view plain copy print ?
  1. "FONT-SIZE: 14px">  
  2. #include    
  3. #include    
  4. int main()  
  5. {  
  6.     Py_Initialize();  
  7.   
  8.     PyObject *pModule = NULL;  
  9.     PyObject *pFunc   = NULL;  
  10.   
  11.     pModule = PyImport_ImportModule("Test");  
  12.     pFunc   = PyObject_GetAttrString(pModule, "hello");   
  13.     PyEval_CallObject(pFunc,NULL);  
  14.     Py_Finalize();  
  15.   
  16.     return 0;  
  17. }  
  18.    

#include 
#include 
int main()
{
    Py_Initialize();

    PyObject *pModule = NULL;
    PyObject *pFunc   = NULL;

    pModule = PyImport_ImportModule("Test");
    pFunc   = PyObject_GetAttrString(pModule, "hello"); 
    PyEval_CallObject(pFunc,NULL);
    Py_Finalize();

    return 0;
}
 


      将这两个文件放在同一文件夹中,你尝试编译。
gcc -I/usr/include/python2.6 -lpython2.6 main.c -o main
看似无误,但是当你运行的时候,你发现报错,---- 段错误。
这是从网上找到的代码,我也深受其害....
之所以这样,原因之一是这段代码写的很糟,没有任何的异常处理,就连暴力的打印方式都没有,如果你这样写:

[cpp] view plain copy print ?
  1. "FONT-SIZE: 18px">"FONT-SIZE: 14px">  
  2. if (pModule == NULL)  
  3. {  
  4.     printf("the pModule is NULL\n");  
  5. }  
  6.    

if (pModule == NULL)
{
    printf("the pModule is NULL\n");
}
 

这样你就会明白pModule是空的,我们根本没能导入,因为python解释器没有找到它,
即使它在当前目录(什么?当前目录也找不到,恩,没错,我的下一篇博客,会给你解释其原因。)

在 Py_Initialize();后,插入这两行代码,把当前目录添加进来。

[cpp] view plain copy print ?
  1. "FONT-SIZE: 14px">  
  2. PyRun_SimpleString("import sys");  
  3. PyRun_SimpleString("sys.path.append('./')");  
  4.    

PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
 

这样就没问题了。在编译一次。
运行

nihao
....
想要了解更多,更详细的用法,去啄木鸟社区吧。

作者:aiqier
csdn博客:http://blog.csdn.net/aiqier627

你可能感兴趣的:(python,opengl)