最近我想使用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