<p>如果将<code>quacker.pyx</code>重命名为<code>quacker.py</code>,实际上一切都是正确的。唯一的问题是您的程序不会在当前目录中搜索python模块,从而导致输出:</p>
<pre><code>Exception NameError: "name 'quack' is not defined" in 'caller.call_quack' ignored
</code></pre>
<p>但是,如果将当前目录添加到PYTHONPATH环境变量中,则输出将成为您期望的目录:</p>
<pre><code>$ PYTHONPATH=".:$PYTHONPATH" ./main
Quack!
</code></pre>
<p>运行python shell时,根据<a href="http://docs.python.org/2/tutorial/modules.html#the-module-search-path">documentation</a>,当前目录(或包含脚本的目录)会自动添加到<code>sys.path</code>变量中,但是在使用<code>Py_Initialize</code>和<code>Py_Finalize</code>创建简单程序时,似乎不会发生这种情况。由于PYTHONPATH变量还用于填充<code>sys.path</code>python变量,因此上面的解决方法会产生正确的结果。</p>
<p>或者,在<code>Py_Intialize</code>行下面,只需执行一些指定为字符串的python代码,就可以向<code>sys.path</code>添加空字符串,如下所示:</p>
<pre><code>PyRun_SimpleString("import sys\nsys.path.insert(0,'')");
</code></pre>
<p>重新编译之后,只需运行<code>./main</code>就可以了。</p>
<h3>编辑</h3>
<p>如果您按照问题中指定的方式运行代码,那么在不重命名<code>quacker.pyx</code>文件的情况下,查看发生了什么事情实际上是很有趣的。在这种情况下,<code>initcaller()</code>函数尝试导入<code>quacker</code>模块,但由于不存在<code>quacker.py</code>或<code>quacker.pyc</code>,因此找不到该模块,并且<code>initcaller()</code>函数会产生错误。</p>
<p>现在,通过引发异常,以python的方式报告此错误。但是<code>main.c</code>文件中的代码没有检查这个。我不是这方面的专家,但是在我的测试中,添加下面的代码<code>initcaller()</code>似乎是有效的:</p>
<pre><code>if (PyErr_Occurred())
{
PyErr_Print();
return -1;
}
</code></pre>
<p>程序的输出随后变为:</p>
<pre><code>Traceback (most recent call last):
File "caller.pyx", line 1, in init caller (caller.c:836)
from quacker import quack
ImportError: No module named quacker
</code></pre>
<p>通过在</em><code>initcaller()</code>之前调用<code>initquacker()</code>函数<em>,模块名<code>quacker</code>已经注册,因此在<code>initcaller()</code>内完成的导入调用将检测到它已经加载,调用将成功。</p>