我有一个c函数,它有以下签名
__declspec( dllexport ) void* setup(int c_force, int c_stepping, int c_iteration, int c_roots,
struct para* c_userdata, double* c_y0,
double c_reltol, double c_abstol)
{
....
return "a pointer";
}
其中para定义如下。我想用这个函数(和其他函数)构建一个dll并从Python访问它。重要的Python行是
^{pr2}$其中cf
,cs
,ci
,cr
是(python)int,para
是下面定义的结构类型,c_y0=(ct_c_double * 2)()
(应该是长度2,从python端和c端都是长度2)和c_reltol
和{c_reltol = ct.c_double(reltol)
。在
当我试图运行我的主应用程序时,我在lib.setup
-函数调用时得到WindowsError: exception: access violation writing xxx
,我不明白为什么。。。在调用lib.setup
之前打印将为传递给函数的参数的值和类型提供以下输出(按顺序)
1 2 2 1 <cparam 'P' (0000000003C84EB0)> <cvode_library.c_double_Array_2 object at 0x0000000003F95BC8> c_double(1e-06) c_double(1e-08)
<type 'int'> <type 'int'> <type 'int'> <type 'int'> <type 'CArgObject'> <class 'cvode_library.c_double_Array_2'> <class 'ctypes.c_double'> <class 'ctypes.c_double'>
我一直试图用this和this问题进行调试,但没有成功。由于c函数的调用签名相当简单,我不明白它为什么会损坏。在
p.S.它在Ubuntu上运行得很好,用__declspec...
替换为extern
c结构定义为
typedef struct para PARA;
struct para
{
double a;
double b;
double c;
};
对应的pystruct为
class para(ct.Structure):
_fields_ = [('a', ct.c_double),
('b', ct.c_double),
('c', ct.c_double)]
编辑c_y0
定义为
y0 = np.array([0., 0.])
c_y0 = (ct.c_double * 2)()
c_y0[0] = y0[0]
c_y0[1] = y0[1]
所有“cvode”函数和N_Vector
都是Sundials suite for solving nonlinear equations的一部分
__declspec( dllexport ) void* setup(int c_force, int c_stepping, int c_iteration, int c_roots,
struct para* c_userdata, double* c_y0,
double c_reltol, double c_abstol)
{
int flag;
N_Vector y;
void* cvode_mem;
PARA* ptr_para;
ptr_para = c_userdata;
// ****** Set up vector with initial conditions ******
y = N_VNew_Serial(2);
NV_Ith_S(y,0) = c_y0[0];
NV_Ith_S(y,1) = c_y0[1];
// ****** Create cvode object with stepping and iteration method ******
if(c_iteration==CV_FUNCTIONAL)
cvode_mem = CVodeCreate(c_stepping, 1); // Functional iteration
else
cvode_mem = CVodeCreate(c_stepping, 2); // Newton interation
if(check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(NULL);
flag = CVodeInit(cvode_mem, ode, 0, y);
if(check_flag(&flag, "CVodeInit", 1)) return(NULL);
// ****** Specify integration tolerances ******
flag = CVodeSStolerances(cvode_mem, c_reltol, c_abstol);
if(check_flag(&flag, "CVodeSStolerances", 1)) return(NULL);
// ****** Set up linear solver module if required ******
if(c_iteration==CV_DENSE_USER)
{
printf("Dense user supplied Jacobian\n");
// Dense user-supplied Jacobian
flag = CVDense(cvode_mem, 2);
if(check_flag(&flag, "CVDense", 1)) return(NULL);
flag = CVDlsSetDenseJacFn(cvode_mem, jac);
if(check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(NULL);
}
else if(c_iteration==CV_DENSE_DQ)
{
// Dense difference quotient Jacobian
flag = CVDlsSetDenseJacFn(cvode_mem, NULL);
if(check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(NULL);
}
// Set optional inputs
flag = CVodeSetUserData(cvode_mem, c_userdata);
if(check_flag(&flag, "CVodeSetUserData", 1)) return(NULL);
// Attach linear solver module
// Specify rootfinding problem
if(c_roots!=ROOTS_OFF)
{
flag = CVodeRootInit(cvode_mem, 1, root_func);
}
return cvode_mem;
}
这是一个MCVE。它表明您的声明是正确的,因此问题很可能出现在函数实现中。如果下面的问题对你不适用,用一个类似的MCVE更新你的问题,重现你的失败。在
测试c
测试.py
^{pr2}$输出
相关问题 更多 >
编程相关推荐