• 《扩展和嵌入python解释器》1.4 模块方法表和初始化函数


    《扩展和嵌入python解释器》1.4 模块方法表和初始化函数

     
    1.4 模块方法表和初始化函数

    下面,我演示如何从Python程序调用spam_system().首先,我们需要在’方法表’列出名称和地址:

    [cpp] view plaincopy
     
    1. static PyMethodDef SpamMethods[] = {  
    2.     ...  
    3.     {"system",  spam_system, METH_VARARGS,  
    4.      "Execute a shell command."},  
    5.     ...  
    6.     {NULL, NULL, 0, NULL}        /* Sentinel */  
    7. };  

    注意第三项("METH_VARARGS")。这是一个标志,用来告诉解释器应使用调用C函数的规则。它一般总是 "METH_VARARGS" 或 "METH_VARARGS | METH_KEYWORDS"; 值0表示PyArg_ParseTuple()函数使用的变量是废弃的。

    当仅使用时"METH_VARARGS",函数希望Python-level参数经由PyArg_ParseTuple()被传递进来。下面提供这个函数的详细信息。

    如果关键字参数被传递到函数,第三个字段的METH_KEYWORDS应被设置为1。在这中情况下, C函数应接受第三个 "PyObject *"参数,此参数是关键字字典。使用PyArg_ParseTupleAndKeywords()函数分析参数。方法表必须在模块初始化函数中传递到解释器。初始化函数必须命名为initname(), 名称是模块名称,并且在模块文件的定义是non-static的。

    [cpp] view plaincopy
     
    1. PyMODINIT_FUNC  
    2. initspam(void)  
    3. {  
    4.     (void) Py_InitModule("spam", SpamMethods);  
    5. }  

    注意: PyMODINIT_FUNC声明函数返回值类型为void,并声明平台所需的特定连接指示,对于C++声明函数为extern "C"类型。

    当Python程序第一次导入spam模块时,initspam()函数被调用 (参见下面关于嵌入Python的说明)。 initspam()函数调用Py_InitModule(),Py_InitModule()函数创建模块对象 (插入到sys.modules字典"spam"键下),并在根据第二个传入参数的表(PyMethodDef结构数组)所创建的对象的基础上,插入内置功能对象。 Py_InitModule()函数返回一个指向它所创建对象的指针(此处没有使用)。如果模块不能正确初始化,函数则因严重错误终止,所以,调用者不必检查错误。

    当嵌入Python时,除非在_PyImport_Inittab表中有一项,否则initspam()不被自动调用。最早的处理此事的办法是:在调用Py_Initialize()后,直接调用你的静态初始化的静态连接模块的initspam()

    [cpp] view plaincopy
     
    1. int  
    2. main(int argc, char *argv[])  
    3. {  
    4.     /* Pass argv[0] to the Python interpreter */  
    5.     Py_SetProgramName(argv[0]);  
    6.   
    7.     /* Initialize the Python interpreter.  Required. */  
    8.     Py_Initialize();  
    9.   
    10.     /* Add a static module */  
    11.     initspam();  
    12. }  


    在Python源代码包,你能找到一个例子:Demo/embed/demo.c。

    注意: 对于一些扩展模块,从sys.modules 模块删除入口点,或在一个进程(或在没有exec()干预的fork()后)中的多个解释器中导入编译后的模块,会产生一些问题。当初始化内部数据结构时,模块作者应该小心处理。还要注意扩展模块能够使用reload()函数,并且调用模块的初始化函数(在本例中是initspam()函数),但如果模块是从可动态加载文件(.so on Unix, .dll on Windows)中加载的,则不会再次加载模块。

    Python源代码发布包中包括更多模块例子,一般在Modules/xxmodule.c。这些文件可以用做模板或简单阅读的例子。源代码发布中包括modulator.py脚本或windows安装提供一个简单的图形界面接口声明函数和要实现的模块对象,并产生一个可以填充的模板。脚本位于Tools/modulator/路径,详细信息请参阅README文件。

  • 相关阅读:
    算法训练 图形显示
    P1002 谁拿了最多奖学金
    java并发编程实战笔记---(第五章)基础构建模块
    java并发编程实战笔记---(第四章)对象的组合
    java并发编程实战笔记---(第三章)对象的共享
    java并发编程实战笔记---(第二章)线程安全:正确性
    栈溢出
    聊聊分布式事务
    路径问题
    apache 软件历史版本查询
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/3817530.html
Copyright © 2020-2023  润新知