c/c++语言开发共享使用Python C API调用C函数两次时的分段错误

最近我想使用C包装器从Fortran调用Python(见这里 )。 下面我发布一个更简单的例子。 函数的第二次调用导致pModule = PyImport_Import(pName)处的分段错误。 我发现问题是from scipy.optimize import newton线 – 如果我评论它一切正常。 任何想法如何解决它?

rootC.c

 #include "rootC.h" #include  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_Append(path, PyString_FromString(".")); pName = PyString_FromString("rootPY"); pModule = PyImport_Import(pName); if (!pModule) { PyErr_Print(); printf("ERROR in pModulen"); 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(); } 

rootC.h

 #ifndef ROOT_H_ #define ROOT_H_ void root_(double*, double*, double*, double*); #endif 

rootPY.py

 from mpmath import polylog, exp from scipy.optimize import newton def root(A,B,t): return 1 

main.c中

 #include "rootC.h" #include  int main() { double A = 0.4, B = 0.3, t = 0.1, x = 0.0; root_(&A,&B,&t,&x); printf("x = %.15fn", x); root_(&A,&B,&t,&x); printf("x = %.15fn", x); return 0; } 

Makefile文件

 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 

    人们也可以这样做:

     #include "rootC.h" #include  #include  void Initialize () { Py_Initialize(); } void Finalize () { Py_Finalize(); } void root_(double* A, double* B, double* t, double* x) { PyObject *pName, *pModule, *pFunc; PyObject *pArgs, *pValue, *sys, *path; static int i; if (i == 0) { ++i; Initialize(); atexit(Finalize); } .... } 

    问题是每次调用函数时初始化和完成python shell。 (它试图不止一次初始化.dll)

    编辑: 链接到资源

    这是我在main.c中的修复…(不是作业的最佳代码)

     int main() { double A = 0.4, B = 0.3, t = 0.1, x = 0.0; bool Stop = false; root_(&A,&B,&t,&x,&Stop); printf("x = %.15fn", x); Stop=true; root_(&A,&B,&t,&x,&Stop); printf("x = %.15fn", x); return 0; } 

    然后在你的rootC.h中

     void root_(double*, double*, double*, double*,bool*); 

    然后在rootC.c中

     #include "rootC.h" #include  void root_(double* A, double* B, double* t, double* x,bool* Stop) { PyObject *pName, *pModule, *pFunc; PyObject *pArgs, *pValue, *sys, *path; if (*Stop==false) { Py_Initialize(); } sys = PyImport_ImportModule("sys"); path = PyObject_GetAttrString(sys, "path"); PyList_Append(path, PyString_FromString(".")); pName = PyString_FromString("rootPY"); pModule = PyImport_Import(pName); if (!pModule) { PyErr_Print(); printf("ERROR in pModulen"); 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); if (*Stop==true) { Py_Finalize(); } } 

    这应该工作:)

      以上就是c/c++开发分享使用Python C API调用C函数两次时的分段错误相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/544829.html

      (0)
      上一篇 2021年1月9日
      下一篇 2021年1月9日

      精彩推荐