回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>最近我想用C包装器从Fortran调用Python(参见<a href="https://stackoverflow.com/questions/34355191/call-python-function-from-fortran-c/34369457#34369457">here</a>)。下面我发布了一个简单的例子。函数的第二次调用导致<code>pModule = PyImport_Import(pName)</code>处的分段错误。我发现问题出在<code>from scipy.optimize import newton</code>行上——如果我注释它,一切都会正常工作。有什么办法解决吗?在</p>
<p><strong>rootC.c</strong></p>
<pre><code>#include "rootC.h"
#include <Python.h>
void root_(double* A, double* B, double* t, double* x)
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue, *sys, *path;
Py_Initialize();
sys = PyImport_ImportModule("sys");
path = PyObject_GetAttrString(sys, "path");
PyList_<a href="https://www.cnpython.com/list/append" class="inner-link">append</a>(path, PyString_FromString("."));
pName = PyString_FromString("rootPY");
pModule = PyImport_Import(pName);
if (!pModule)
{
PyErr_Print();
printf("ERROR in pModule\n");
exit(1);
}
pFunc = PyObject_GetAttrString(pModule, "root");
pArgs = PyTuple_New(3);
PyTuple_SetItem(pArgs, 0, PyFloat_FromDouble((*A)));
PyTuple_SetItem(pArgs, 1, PyFloat_FromDouble((*B)));
PyTuple_SetItem(pArgs, 2, PyFloat_FromDouble((*t)));
pValue = PyObject_CallObject(pFunc, pArgs);
*x = PyFloat_AsDouble(pValue);
Py_Finalize();
}
</code></pre>
<p><strong>rootC.h</strong></p>
^{pr2}$
<p><strong>根py.py</strong></p>
<pre><code>from mpmath import polylog, exp
from scipy.optimize import newton
def root(A,B,t):
return 1
</code></pre>
<p><strong>main.c</strong></p>
<pre><code>#include "rootC.h"
#include <stdio.h>
int main()
{
double A = 0.4, B = 0.3, t = 0.1, x = 0.0;
root_(&A,&B,&t,&x);
printf("x = %.15f\n", x);
root_(&A,&B,&t,&x);
printf("x = %.15f\n", x);
return 0;
}
</code></pre>
<p><strong>生成文件</strong></p>
<pre><code>CC = gcc
FC = gfortran
CFLAGS = -I/usr/include/python2.7
LFLAGS = -L/usr/local/lib -lpython2.7 -lm
.PHONY: all clean
all: main
main: main.o rootC.o
$(CC) $^ -o $@ $(LFLAGS)
main.o: main.c
$(CC) $(CFLAGS) -c $< -o $@
rootC.o: rootC.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o
</code></pre>