614 lines
71 KiB
HTML
614 lines
71 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||
<head>
|
||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||
|
||
<title>扩展/嵌入常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script src="../_static/jquery.js"></script>
|
||
<script src="../_static/underscore.js"></script>
|
||
<script src="../_static/doctools.js"></script>
|
||
<script src="../_static/language_data.js"></script>
|
||
<script src="../_static/translations.js"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="在 Python 3.8.20 文档 中搜索"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||
<link rel="index" title="索引" href="../genindex.html" />
|
||
<link rel="search" title="搜索" href="../search.html" />
|
||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||
<link rel="next" title="Python在Windows上的常见问题" href="windows.html" />
|
||
<link rel="prev" title="代码库和插件 FAQ" href="library.html" />
|
||
<link rel="canonical" href="https://docs.python.org/3/faq/extending.html" />
|
||
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/menu.js"></script>
|
||
|
||
</head>
|
||
<body>
|
||
<div class="mobile-nav">
|
||
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
|
||
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<nav class="nav-content" role="navigation">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Logo"/>
|
||
</a>
|
||
<div class="version_switcher_placeholder"></div>
|
||
<form role="search" class="search" action="../search.html" method="get">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
|
||
<path fill-rule="nonzero"
|
||
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
|
||
</svg>
|
||
<input type="text" name="q" aria-label="快速搜索"/>
|
||
<input type="submit" value="转向"/>
|
||
</form>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">扩展/嵌入常见问题</a><ul>
|
||
<li><a class="reference internal" href="#can-i-create-my-own-functions-in-c">可以使用 C 语言创建自己的函数吗?</a></li>
|
||
<li><a class="reference internal" href="#id2">可以使用 C++ 语言创建自己的函数吗?</a></li>
|
||
<li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives">C很难写,有没有其他选择?</a></li>
|
||
<li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c">如何在 C 中执行任意 Python 语句?</a></li>
|
||
<li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c">如何在 C 中对任意 Python 表达式求值?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object">如何从Python对象中提取C的值?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">如何使用Py_BuildValue()创建任意长度的元组?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c">如何从C调用对象的方法?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c">如何从C访问用Python编写的模块?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python">如何在 Python 中对接 C ++ 对象?</a></li>
|
||
<li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why">我使用Setup文件添加了一个模块,为什么make失败了?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-debug-an-extension">如何调试扩展?</a></li>
|
||
<li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input">如何区分“输入不完整”和“输入无效”?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></li>
|
||
<li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="library.html"
|
||
title="上一章">代码库和插件 FAQ</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="windows.html"
|
||
title="下一章">Python在Windows上的常见问题</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/extending.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||
你应当升级版本,并阅读
|
||
<a href="/3/faq/extending.html"> Python 当前稳定版本的文档</a>.
|
||
</div>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
accesskey="I">索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||
accesskey="N">下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="library.html" title="代码库和插件 FAQ"
|
||
accesskey="P">上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="extending-embedding-faq">
|
||
<h1><a class="toc-backref" href="#id3">扩展/嵌入常见问题</a><a class="headerlink" href="#extending-embedding-faq" title="永久链接至标题">¶</a></h1>
|
||
<div class="contents topic" id="id1">
|
||
<p class="topic-title">目录</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#extending-embedding-faq" id="id3">扩展/嵌入常见问题</a></p>
|
||
<ul>
|
||
<li><p><a class="reference internal" href="#can-i-create-my-own-functions-in-c" id="id4">可以使用 C 语言创建自己的函数吗?</a></p></li>
|
||
<li><p><a class="reference internal" href="#id2" id="id5">可以使用 C++ 语言创建自己的函数吗?</a></p></li>
|
||
<li><p><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives" id="id6">C很难写,有没有其他选择?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c" id="id7">如何在 C 中执行任意 Python 语句?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" id="id8">如何在 C 中对任意 Python 表达式求值?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object" id="id9">如何从Python对象中提取C的值?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" id="id10">如何使用Py_BuildValue()创建任意长度的元组?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c" id="id11">如何从C调用对象的方法?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" id="id12">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c" id="id13">如何从C访问用Python编写的模块?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python" id="id14">如何在 Python 中对接 C ++ 对象?</a></p></li>
|
||
<li><p><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" id="id15">我使用Setup文件添加了一个模块,为什么make失败了?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-debug-an-extension" id="id16">如何调试扩展?</a></p></li>
|
||
<li><p><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" id="id17">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input" id="id18">如何区分“输入不完整”和“输入无效”?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" id="id19">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></p></li>
|
||
<li><p><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" id="id20">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<section id="can-i-create-my-own-functions-in-c">
|
||
<h2><a class="toc-backref" href="#id4">可以使用 C 语言创建自己的函数吗?</a><a class="headerlink" href="#can-i-create-my-own-functions-in-c" title="永久链接至标题">¶</a></h2>
|
||
<p>是的,您可以在C中创建包含函数、变量、异常甚至新类型的内置模块。在文档 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">扩展和嵌入 Python 解释器</span></a> 中有说明。</p>
|
||
<p>大多数中级或高级的Python书籍也涵盖这个主题。</p>
|
||
</section>
|
||
<section id="id2">
|
||
<h2><a class="toc-backref" href="#id5">可以使用 C++ 语言创建自己的函数吗?</a><a class="headerlink" href="#id2" title="永久链接至标题">¶</a></h2>
|
||
<p>是的,可以使用C ++中兼容C的功能。 在Python include文件周围放置` <cite>extern“C”{...}`</cite> ,并在Python解释器调用的每个函数之前放置 <code class="docutils literal notranslate"><span class="pre">extern“C”</span></code> 。 具有构造函数的全局或静态C ++对象可能不是一个好主意。</p>
|
||
</section>
|
||
<section id="writing-c-is-hard-are-there-any-alternatives">
|
||
<span id="c-wrapper-software"></span><h2><a class="toc-backref" href="#id6">C很难写,有没有其他选择?</a><a class="headerlink" href="#writing-c-is-hard-are-there-any-alternatives" title="永久链接至标题">¶</a></h2>
|
||
<p>编写自己的C扩展有很多选择,具体取决于您要做的事情。</p>
|
||
<p><a class="reference external" href="http://cython.org">Cython</a> 及其相关的 <a class="reference external" href="https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/">Pyrex</a> 是接受稍微修改过的Python形式并生成相应C代码的编译器。 Cython和Pyrex可以编写扩展而无需学习Python的C API。</p>
|
||
<p>如果需要连接到某些当前不存在Python扩展的C或C ++库,可以尝试使用 <a class="reference external" href="http://www.swig.org">SWIG</a> 等工具包装库的数据类型和函数。 <a class="reference external" href="https://riverbankcomputing.com/software/sip/intro">SIP</a> , <a class="reference external" href="http://cxx.sourceforge.net/">CXX</a> <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">Boost</a> , 或 <a class="reference external" href="https://github.com/scipy/weave">Weave</a> 也是包装C ++库的替代方案。</p>
|
||
</section>
|
||
<section id="how-can-i-execute-arbitrary-python-statements-from-c">
|
||
<h2><a class="toc-backref" href="#id7">如何在 C 中执行任意 Python 语句?</a><a class="headerlink" href="#how-can-i-execute-arbitrary-python-statements-from-c" title="永久链接至标题">¶</a></h2>
|
||
<p>执行此操作的最高层级函数为 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a>,它接受单个字符串参数用于在模块 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 的上下文中执行并在成功时返回 <code class="docutils literal notranslate"><span class="pre">0</span></code> 而在发生异常 (包括 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>) 时返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code>。 如果你想要更多可控性,可以使用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a>;请在 <code class="docutils literal notranslate"><span class="pre">Python/pythonrun.c</span></code> 中查看 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a> 的源码。</p>
|
||
</section>
|
||
<section id="how-can-i-evaluate-an-arbitrary-python-expression-from-c">
|
||
<h2><a class="toc-backref" href="#id8">如何在 C 中对任意 Python 表达式求值?</a><a class="headerlink" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" title="永久链接至标题">¶</a></h2>
|
||
<p>可以调用前一问题中介绍的函数 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a> 并附带起始标记符 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_eval_input" title="Py_eval_input"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_eval_input</span></code></a>;它会解析表达式,对其求值并返回结果值。</p>
|
||
</section>
|
||
<section id="how-do-i-extract-c-values-from-a-python-object">
|
||
<h2><a class="toc-backref" href="#id9">如何从Python对象中提取C的值?</a><a class="headerlink" href="#how-do-i-extract-c-values-from-a-python-object" title="永久链接至标题">¶</a></h2>
|
||
<p>这取决于对象的类型。 如果是元组,<a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Size" title="PyTuple_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_GetItem" title="PyTuple_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_GetItem()</span></code></a> 可返回指定序号上的项。 对于列表也有类似的函数 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyListSize()</span></code> 和 <a class="reference internal" href="../c-api/list.html#c.PyList_GetItem" title="PyList_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItem()</span></code></a>。</p>
|
||
<p>对于字节串,<a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Size" title="PyBytes_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_AsStringAndSize" title="PyBytes_AsStringAndSize"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_AsStringAndSize()</span></code></a> 提供一个指向其值和长度的指针。 请注意 Python 字节串可能为空,因此 C 的 <code class="xref c c-func docutils literal notranslate"><span class="pre">strlen()</span></code> 不应被使用。</p>
|
||
<p>要检测一个对象的类型,首先要确保它不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>,然后使用 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Check" title="PyBytes_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Check()</span></code></a>, <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Check" title="PyTuple_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Check()</span></code></a>, <a class="reference internal" href="../c-api/list.html#c.PyList_Check" title="PyList_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_Check()</span></code></a> 等等。</p>
|
||
<p>还有一个针对 Python 对象的高层级 API,通过所谓的‘抽象’接口提供 —— 请参阅 <code class="docutils literal notranslate"><span class="pre">Include/abstract.h</span></code> 了解详情。 它允许使用 <a class="reference internal" href="../c-api/sequence.html#c.PySequence_Length" title="PySequence_Length"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_Length()</span></code></a>, <a class="reference internal" href="../c-api/sequence.html#c.PySequence_GetItem" title="PySequence_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_GetItem()</span></code></a> 这样的调用来与任意种类的 Python 序列进行对接,此外还可使用许多其他有用的协议例如数字 (<a class="reference internal" href="../c-api/number.html#c.PyNumber_Index" title="PyNumber_Index"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyNumber_Index()</span></code></a> 等) 以及 PyMapping API 中的各种映射等等。</p>
|
||
</section>
|
||
<section id="how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">
|
||
<h2><a class="toc-backref" href="#id10">如何使用Py_BuildValue()创建任意长度的元组?</a><a class="headerlink" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" title="永久链接至标题">¶</a></h2>
|
||
<p>不可以。应该使用 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Pack" title="PyTuple_Pack"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Pack()</span></code></a> 。</p>
|
||
</section>
|
||
<section id="how-do-i-call-an-object-s-method-from-c">
|
||
<h2><a class="toc-backref" href="#id11">如何从C调用对象的方法?</a><a class="headerlink" href="#how-do-i-call-an-object-s-method-from-c" title="永久链接至标题">¶</a></h2>
|
||
<p>可以使用 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallMethod" title="PyObject_CallMethod"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallMethod()</span></code></a> 函数来调用某个对象的任意方法。 形参为该对象、要调用的方法名、类似 <a class="reference internal" href="../c-api/arg.html#c.Py_BuildValue" title="Py_BuildValue"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_BuildValue()</span></code></a> 所用的格式字符串以及要传给方法的参数值:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
|
||
<span class="nf">PyObject_CallMethod</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">object</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">method_name</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">arg_format</span><span class="p">,</span><span class="w"> </span><span class="p">...);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>这适用于任何具有方法的对象 —— 不论是内置方法还是用户自定义方法。 你需要负责对返回值进行最终的 <a class="reference internal" href="../c-api/refcounting.html#c.Py_DECREF" title="Py_DECREF"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DECREF()</span></code></a> 处理。</p>
|
||
<p>例如调用某个文件对象的 "seek" 方法并传入参数 10, 0 (假定文件对象的指针为 "f"):</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_CallMethod</span><span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="w"> </span><span class="s">"seek"</span><span class="p">,</span><span class="w"> </span><span class="s">"(ii)"</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">exception</span><span class="w"> </span><span class="n">occurred</span><span class="w"> </span><span class="p">...</span>
|
||
<span class="p">}</span>
|
||
<span class="k">else</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">res</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>请注意由于 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallObject" title="PyObject_CallObject"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallObject()</span></code></a> <em>总是</em> 接受一个元组作为参数列表,要调用不带参数的函数,则传入格式为 "()",要调用只带一个参数的函数,则应将参数包含于圆括号中,例如 "(i)"。</p>
|
||
</section>
|
||
<section id="how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">
|
||
<h2><a class="toc-backref" href="#id12">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a><a class="headerlink" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" title="永久链接至标题">¶</a></h2>
|
||
<p>在 Python 代码中,定义一个支持 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法的对象。 将此对象赋值给 <a class="reference internal" href="../library/sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a> 和 <a class="reference internal" href="../library/sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a>。 调用 print_error 或者只是允许标准回溯机制生效。 在此之后,输出将转往你的 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法所指向的任何地方。</p>
|
||
<p>做到这一点的最简单方式是使用 <a class="reference internal" href="../library/io.html#io.StringIO" title="io.StringIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.StringIO</span></code></a> 类:</p>
|
||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
|
||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'hello world!'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>
|
||
<span class="go">foo</span>
|
||
<span class="go">hello world!</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>实现同样效果的自定义对象看起来是这样的:</p>
|
||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
|
||
<span class="gp">>>> </span><span class="k">class</span> <span class="nc">StdoutCatcher</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">TextIOBase</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="gp">... </span> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stuff</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">stuff</span><span class="p">)</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">sys</span>
|
||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">StdoutCatcher</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'hello world!'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">data</span><span class="p">))</span>
|
||
<span class="go">foo</span>
|
||
<span class="go">hello world!</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="how-do-i-access-a-module-written-in-python-from-c">
|
||
<h2><a class="toc-backref" href="#id13">如何从C访问用Python编写的模块?</a><a class="headerlink" href="#how-do-i-access-a-module-written-in-python-from-c" title="永久链接至标题">¶</a></h2>
|
||
<p>你可以通过如下方式获得一个指向模块对象的指针:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">module</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyImport_ImportModule</span><span class="p">(</span><span class="s">"<modulename>"</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>如果模块尚未被导入(即它还不存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中),这会初始化该模块;否则它只是简单地返回 <code class="docutils literal notranslate"><span class="pre">sys.modules["<modulename>"]</span></code> 的值。 请注意它并不会将模块加入任何命名空间 —— 它只是确保模块被初始化并存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中。</p>
|
||
<p>之后你就可以通过如下方式来访问模块的属性(即模块中定义的任何名称):</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">attr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">module</span><span class="p">,</span><span class="w"> </span><span class="s">"<attrname>"</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>调用 <a class="reference internal" href="../c-api/object.html#c.PyObject_SetAttrString" title="PyObject_SetAttrString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_SetAttrString()</span></code></a> 为模块中的变量赋值也是可以的。</p>
|
||
</section>
|
||
<section id="how-do-i-interface-to-c-objects-from-python">
|
||
<h2><a class="toc-backref" href="#id14">如何在 Python 中对接 C ++ 对象?</a><a class="headerlink" href="#how-do-i-interface-to-c-objects-from-python" title="永久链接至标题">¶</a></h2>
|
||
<p>根据你的需求,可以选择许多方式。 手动的实现方式请查阅 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">"扩展与嵌入" 文档</span></a> 来入门。 需要知道的是对于 Python 运行时系统来说,C 和 C++ 并不没有太大的区别 —— 因此围绕一个 C 结构(指针)类型构建新 Python 对象的策略同样适用于 C++ 对象。</p>
|
||
<p>有关C ++库,请参阅 <a class="reference internal" href="#c-wrapper-software"><span class="std std-ref">C很难写,有没有其他选择?</span></a></p>
|
||
</section>
|
||
<section id="i-added-a-module-using-the-setup-file-and-the-make-fails-why">
|
||
<h2><a class="toc-backref" href="#id15">我使用Setup文件添加了一个模块,为什么make失败了?</a><a class="headerlink" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" title="永久链接至标题">¶</a></h2>
|
||
<p>安装程序必须以换行符结束,如果没有换行符,则构建过程将失败。 (修复这个需要一些丑陋的shell脚本编程,而且这个bug很小,看起来不值得花这么大力气。)</p>
|
||
</section>
|
||
<section id="how-do-i-debug-an-extension">
|
||
<h2><a class="toc-backref" href="#id16">如何调试扩展?</a><a class="headerlink" href="#how-do-i-debug-an-extension" title="永久链接至标题">¶</a></h2>
|
||
<p>将GDB与动态加载的扩展名一起使用时,在加载扩展名之前,不能在扩展名中设置断点。</p>
|
||
<p>在您的 <code class="docutils literal notranslate"><span class="pre">.gdbinit</span></code> 文件中(或交互式)添加命令:</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>br _PyImport_LoadDynamicModule
|
||
</pre></div>
|
||
</div>
|
||
<p>然后运行GDB:</p>
|
||
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>gdb<span class="w"> </span>/local/bin/python
|
||
<span class="go">gdb) run myscript.py</span>
|
||
<span class="go">gdb) continue # repeat until your extension is loaded</span>
|
||
<span class="go">gdb) finish # so that your extension is loaded</span>
|
||
<span class="go">gdb) br myfunction.c:50</span>
|
||
<span class="go">gdb) continue</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">
|
||
<h2><a class="toc-backref" href="#id17">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a><a class="headerlink" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" title="永久链接至标题">¶</a></h2>
|
||
<p>大多数打包的Python版本不包含 <code class="file docutils literal notranslate"><span class="pre">/usr/lib/python2.</span><em><span class="pre">x</span></em><span class="pre">/config/</span></code> 目录,该目录中包含编译Python扩展所需的各种文件。</p>
|
||
<p>对于Red Hat,安装python-devel RPM以获取必要的文件。</p>
|
||
<p>对于Debian,运行 <code class="docutils literal notranslate"><span class="pre">apt-get</span> <span class="pre">install</span> <span class="pre">python-dev</span></code> 。</p>
|
||
</section>
|
||
<section id="how-do-i-tell-incomplete-input-from-invalid-input">
|
||
<h2><a class="toc-backref" href="#id18">如何区分“输入不完整”和“输入无效”?</a><a class="headerlink" href="#how-do-i-tell-incomplete-input-from-invalid-input" title="永久链接至标题">¶</a></h2>
|
||
<p>有时,希望模仿Python交互式解释器的行为,在输入不完整时(例如,您键入了“if”语句的开头,或者没有关闭括号或三个字符串引号),给出一个延续提示,但当输入无效时,立即给出一条语法错误消息。</p>
|
||
<p>在Python中,您可以使用 <a class="reference internal" href="../library/codeop.html#module-codeop" title="codeop: Compile (possibly incomplete) Python code."><code class="xref py py-mod docutils literal notranslate"><span class="pre">codeop</span></code></a> 模块,该模块非常接近解析器的行为。例如,IDLE就使用了这个。</p>
|
||
<p>在C中执行此操作的最简单方法是调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> (可能在单独的线程中)并让Python解释器为您处理输入。您还可以设置 <a class="reference internal" href="../c-api/veryhigh.html#c.PyOS_ReadlineFunctionPointer" title="PyOS_ReadlineFunctionPointer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyOS_ReadlineFunctionPointer()</span></code></a> 指向您的自定义输入函数。有关更多提示,请参阅 <code class="docutils literal notranslate"><span class="pre">Modules/readline.c</span></code> 和 <code class="docutils literal notranslate"><span class="pre">Parser/myreadline.c</span></code> 。</p>
|
||
<p>但是,有时必须在与其他应用程序相同的线程中运行嵌入式Python解释器,并且不能允许 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> 在等待用户输入时停止。那么另一个解决方案是调用 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyParser_ParseString()</span></code> 并测试 <code class="docutils literal notranslate"><span class="pre">e.error</span></code> 等于 <code class="docutils literal notranslate"><span class="pre">E_EOF</span></code> ,如果等于,就意味着输入不完整。这是一个示例代码片段,未经测试,灵感来自Alex Farber的代码:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Python.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><node.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><errcode.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><grammar.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><parsetok.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><compile.h></span>
|
||
|
||
<span class="kt">int</span><span class="w"> </span><span class="nf">testcomplete</span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">code</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="cm">/* code should end in \n */</span>
|
||
<span class="w"> </span><span class="cm">/* return -1 for error, 0 for incomplete, 1 for complete */</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">*</span><span class="n">n</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="n">perrdetail</span><span class="w"> </span><span class="n">e</span><span class="p">;</span>
|
||
|
||
<span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyParser_ParseString</span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">_PyParser_Grammar</span><span class="p">,</span>
|
||
<span class="w"> </span><span class="n">Py_file_input</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">e</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">error</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">E_EOF</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
|
||
<span class="w"> </span><span class="n">PyNode_Free</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>另一个解决方案是尝试使用 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_CompileString" title="Py_CompileString"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_CompileString()</span></code></a> 编译接收到的字符串。如果编译时没有出现错误,请尝试通过调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyEval_EvalCode" title="PyEval_EvalCode"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_EvalCode()</span></code></a> 来执行返回的代码对象。否则,请将输入保存到以后。如果编译失败,找出是错误还是只需要更多的输入-从异常元组中提取消息字符串,并将其与字符串 “分析时意外的EOF” 进行比较。下面是使用GNUreadline库的完整示例(您可能希望在调用readline()时忽略 <strong>SIGINT</strong> ):</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><stdio.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><readline.h></span>
|
||
|
||
<span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Python.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><object.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><compile.h></span>
|
||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><eval.h></span>
|
||
|
||
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="p">[])</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="p">,</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="cm">/* lengths of line, code */</span>
|
||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">ps1</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">">>> "</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">ps2</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"... "</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">loc</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">trb</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">dum</span><span class="p">;</span>
|
||
|
||
<span class="w"> </span><span class="n">Py_Initialize</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">loc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyDict_New</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">glb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyDict_New</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">PyDict_SetItemString</span><span class="w"> </span><span class="p">(</span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="s">"__builtins__"</span><span class="p">,</span><span class="w"> </span><span class="n">PyEval_GetBuiltins</span><span class="w"> </span><span class="p">());</span>
|
||
|
||
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">done</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">readline</span><span class="w"> </span><span class="p">(</span><span class="n">prompt</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">line</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Ctrl-D pressed */</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="k">else</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="n">add_history</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span><span class="w"> </span><span class="cm">/* save non-empty lines */</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">)</span><span class="w"> </span><span class="cm">/* nothing in code yet */</span>
|
||
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="k">else</span>
|
||
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">realloc</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">)</span><span class="w"> </span><span class="cm">/* out of memory */</span>
|
||
<span class="w"> </span><span class="n">exit</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="cm">/* code was empty, so */</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\0'</span><span class="p">;</span><span class="w"> </span><span class="cm">/* keep strncat happy */</span>
|
||
|
||
<span class="w"> </span><span class="n">strncat</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">);</span><span class="w"> </span><span class="cm">/* append line to code */</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"> </span><span class="cm">/* append '\n' to code */</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\0'</span><span class="p">;</span>
|
||
|
||
<span class="w"> </span><span class="n">src</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_CompileString</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="s">"<stdin>"</span><span class="p">,</span><span class="w"> </span><span class="n">Py_single_input</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">src</span><span class="p">)</span><span class="w"> </span><span class="cm">/* compiled just fine - */</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ps1</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* ">>> " or */</span>
|
||
<span class="w"> </span><span class="sc">'\n'</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">])</span><span class="w"> </span><span class="cm">/* "... " and double '\n' */</span>
|
||
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* so execute it */</span>
|
||
<span class="w"> </span><span class="n">dum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyEval_EvalCode</span><span class="w"> </span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="n">loc</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">dum</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">src</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyErr_Occurred</span><span class="w"> </span><span class="p">())</span>
|
||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="cm">/* syntax error or E_EOF? */</span>
|
||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyErr_ExceptionMatches</span><span class="w"> </span><span class="p">(</span><span class="n">PyExc_SyntaxError</span><span class="p">))</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">PyErr_Fetch</span><span class="w"> </span><span class="p">(</span><span class="o">&</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">trb</span><span class="p">);</span><span class="w"> </span><span class="cm">/* clears exception! */</span>
|
||
|
||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyArg_ParseTuple</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="s">"sO"</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="o">&&</span>
|
||
<span class="w"> </span><span class="o">!</span><span class="n">strcmp</span><span class="w"> </span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="s">"unexpected EOF while parsing"</span><span class="p">))</span><span class="w"> </span><span class="cm">/* E_EOF */</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">exc</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">trb</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps2</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cm">/* some other syntax error */</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">PyErr_Restore</span><span class="w"> </span><span class="p">(</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="n">trb</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cm">/* some non-syntax error */</span>
|
||
<span class="w"> </span><span class="p">{</span>
|
||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
|
||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
<span class="w"> </span><span class="p">}</span>
|
||
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">glb</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">Py_Finalize</span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">
|
||
<h2><a class="toc-backref" href="#id19">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a><a class="headerlink" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" title="永久链接至标题">¶</a></h2>
|
||
<p>要动态加载g ++扩展模块,必须重新编译Python,要使用g ++重新链接(在Python Modules Makefile中更改LINKCC),及链接扩展模块(例如: <code class="docutils literal notranslate"><span class="pre">g++</span> <span class="pre">-shared</span> <span class="pre">-o</span> <span class="pre">mymodule.so</span> <span class="pre">mymodule.o</span></code> )。</p>
|
||
</section>
|
||
<section id="can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">
|
||
<h2><a class="toc-backref" href="#id20">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a><a class="headerlink" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" title="永久链接至标题">¶</a></h2>
|
||
<p>是的,您可以继承内置类,例如 <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a> , <a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> , <a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 等。</p>
|
||
<p>Boost Python库(BPL,http://www.boost.org/libs/python/doc/index.html)提供了一种从C ++执行此操作的方法(即,您可以使用BPL继承自C ++编写的扩展类 )。</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">目录</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">扩展/嵌入常见问题</a><ul>
|
||
<li><a class="reference internal" href="#can-i-create-my-own-functions-in-c">可以使用 C 语言创建自己的函数吗?</a></li>
|
||
<li><a class="reference internal" href="#id2">可以使用 C++ 语言创建自己的函数吗?</a></li>
|
||
<li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives">C很难写,有没有其他选择?</a></li>
|
||
<li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c">如何在 C 中执行任意 Python 语句?</a></li>
|
||
<li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c">如何在 C 中对任意 Python 表达式求值?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object">如何从Python对象中提取C的值?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">如何使用Py_BuildValue()创建任意长度的元组?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c">如何从C调用对象的方法?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c">如何从C访问用Python编写的模块?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python">如何在 Python 中对接 C ++ 对象?</a></li>
|
||
<li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why">我使用Setup文件添加了一个模块,为什么make失败了?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-debug-an-extension">如何调试扩展?</a></li>
|
||
<li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input">如何区分“输入不完整”和“输入无效”?</a></li>
|
||
<li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></li>
|
||
<li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>上一个主题</h4>
|
||
<p class="topless"><a href="library.html"
|
||
title="上一章">代码库和插件 FAQ</a></p>
|
||
<h4>下一个主题</h4>
|
||
<p class="topless"><a href="windows.html"
|
||
title="下一章">Python在Windows上的常见问题</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>本页</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/extending.rst"
|
||
rel="nofollow">显示源代码
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>导航</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="总目录"
|
||
>索引</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python 模块索引"
|
||
>模块</a> |</li>
|
||
<li class="right" >
|
||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||
>下一页</a> |</li>
|
||
<li class="right" >
|
||
<a href="library.html" title="代码库和插件 FAQ"
|
||
>上一页</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.8.20 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||
<input type="submit" value="转向" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
|
||
<br />
|
||
This page is licensed under the Python Software Foundation License Version 2.
|
||
<br />
|
||
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
|
||
<br />
|
||
|
||
<br />
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
<br />
|
||
|
||
最后更新于 12月 09, 2024.
|
||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||
<br />
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |