Files
hustoj/web/python-docs/faq/extending.html
2025-03-09 17:10:56 +08:00

614 lines
71 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>扩展/嵌入常见问题 &#8212; 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> &#187;</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> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> &#187;</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>例如调用某个文件对象的 &quot;seek&quot; 方法并传入参数 10, 0 (假定文件对象的指针为 &quot;f&quot;):</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">&quot;seek&quot;</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;(ii)&quot;</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> 接受一个元组作为参数列表,要调用不带参数的函数,则传入格式为 &quot;()&quot;,要调用只带一个参数的函数,则应将参数包含于圆括号中,例如 &quot;(i)&quot;</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">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </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">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello world!&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </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">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </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">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </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">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello world!&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </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">&#39;&#39;</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">&quot;&lt;modulename&gt;&quot;</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[&quot;&lt;modulename&gt;&quot;]</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">&quot;&lt;attrname&gt;&quot;</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">&quot;扩展与嵌入&quot; 文档</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">&lt;Python.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;node.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;errcode.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;grammar.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;parsetok.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;compile.h&gt;</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">&amp;</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">&amp;</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">&lt;stdio.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;readline.h&gt;</span>
<span class="cp">#define PY_SSIZE_T_CLEAN</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;Python.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;object.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;compile.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;eval.h&gt;</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">&quot;&gt;&gt;&gt; &quot;</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">&quot;... &quot;</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">&quot;__builtins__&quot;</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">&gt;</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">&#39;\0&#39;</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">&#39;\n&#39;</span><span class="p">;</span><span class="w"> </span><span class="cm">/* append &#39;\n&#39; 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">&#39;\0&#39;</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">&quot;&lt;stdin&gt;&quot;</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">/* &quot;&gt;&gt;&gt; &quot; or */</span>
<span class="w"> </span><span class="sc">&#39;\n&#39;</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">/* &quot;... &quot; and double &#39;\n&#39; */</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">&amp;</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</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">&quot;sO&quot;</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;&amp;</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">&quot;unexpected EOF while parsing&quot;</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库BPLhttp//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> &#187;</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> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> &#187;</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">
&copy; <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>