首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Python两次调用C函数时的分割错误

用Python两次调用C函数时的分割错误
EN

Stack Overflow用户
提问于 2015-12-19 13:17:55
回答 2查看 2.8K关注 0票数 4

最近,我想使用C包装器从Fortran调用Python (参见here)。下面我发布了一个简单的例子。函数的第二次调用导致pModule = PyImport_Import(pName)的分割故障。我发现问题在于from scipy.optimize import newton行--如果我评论它,一切都很好。有什么办法解决吗?

rootC.c

代码语言:javascript
复制
#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_Append(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();
}

rootC.h

代码语言:javascript
复制
#ifndef ROOT_H_
#define ROOT_H_

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

#endif

rootPY.py

代码语言:javascript
复制
from mpmath import polylog, exp
from scipy.optimize import newton

def root(A,B,t):   
    return 1

main.c

代码语言:javascript
复制
#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;
}

Makefile

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-19 20:51:57

人们也可以这样做:

代码语言:javascript
复制
#include "rootC.h"
#include <Python.h>
#include <stdlib.h>

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);
    }

    ....
}
票数 3
EN

Stack Overflow用户

发布于 2015-12-19 17:17:46

问题是每次调用python时都要初始化和最后完成该函数。(它正在尝试多次初始化.dll )

编辑:Link to resource

这是我的办法..。(这不是工作的最佳代码)在你的主机上

代码语言:javascript
复制
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 = %.15f\n", x);

    Stop=true;
    root_(&A,&B,&t,&x,&Stop);
    printf("x = %.15f\n", x);



    return 0;
}

然后在你的根部

代码语言:javascript
复制
void root_(double*, double*, double*, double*,bool*);

然后在rootC.c .

代码语言:javascript
复制
#include "rootC.h"
#include <Python.h>

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 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);
    if (*Stop==true)
    {
        Py_Finalize();
    }
}

(这应有效:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34371221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档