从 python 调用静态链接的 C 库会在 windows 上永远挂起,但不会在 OSX 或 linux 上挂起
Calling statically linked C library from python hangs forever on windows but not OSX or linux
我有以下 c 库,tridiag.c
:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define PI 3.14159265358979323846
typedef struct tridiag_matrix{
double *a;
double *b;
double *c;
} Tridiag_M;
inline
double interpl_4(double a,double b,double c,double d,double frac){
return b*(1-frac)+c*frac;
};
double cubic_interpolate( float y0, float y1, float y2, float y3, float mu ) {
double a0, a1, a2, a3, mu2;
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1; //p
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 );
}
inline double cos_interpl(double a,double b,double frac){
double mu2=(1-cos(frac*PI))/2;
return a*(1-mu2)+b*mu2;
};
void solve_tridiagonal(Tridiag_M *t, double *r,double *x,int N) {
int in;
double *cprime=(double*) malloc(N*sizeof(double));
cprime[0] = t->c[0] / t->b[0];
x[0] = r[0] / t->b[0];
/* loop from 1 to N - 1 inclusive */
for (in = 1; in < N; in++) {
double m = 1.0 / (t->b[in] - t->a[in] * cprime[in - 1]);
cprime[in] = t->c[in] * m;
x[in] = (r[in] - t->a[in] * x[in - 1]) * m;
}
/* loop from N - 2 to 0 inclusive, safely testing loop end condition */
for (in = N - 1; in-- > 0; ){
x[in] = x[in] - cprime[in] * x[in + 1]; /*wrong cprime[in] ebasta!*/
}
/* free scratch space */
free(cprime);
}
void delay_line(double *Y, int *delay0,int *delay1,int *delay2,int *delay3,double *dev,double *out,int M,int N){
int i;
for(i=0;i<N;i++){
int k=M*i;
if(dev[i]<1){
out[i]=cubic_interpolate(Y[k+delay0[i]],Y[k+delay1[i]],Y[k+delay2[i]],Y[k+delay3[i]],dev[i]);
}
else{
out[i]=cubic_interpolate(Y[k+(delay0[i]+1)%M],Y[k+(delay1[i]+1)%M],Y[k+(delay2[i]+1)%M],Y[k+(delay3[i]+1)%M],dev[i]-1);
}
}
}
void calculate_g(double *V,double *Y,double *sherad_factor,double *sheraD,double *sheraRho,double *Yzweig,double *omega,double *g,double d_m_factor,const int n){
int i;
g[0]=d_m_factor*V[0];
for(i=1;i<n;i++){
g[i]=sherad_factor[i]*sheraD[i]*V[i]+omega[i]*omega[i]*(Y[i]+sheraRho[i]*Yzweig[i]);
}
}
我正在使用 gcc 4.5.0 / mingw32 在 Windows 7 64 位上编译它。
gcc -shared -m32 -o -Wall tridiag.so_windows tridiag.c
。
这完全退出,没有输出。
在 python 3.5.x 中,我正在加载库:
# load C library
libtrisolv = np.ctypeslib.load_library(tridiagName, resources_root)
# load tridiagonal solver function and defines input
libtrisolv.solve_tridiagonal.restype = None
libtrisolv.solve_tridiagonal.argtypes = [ctypes.POINTER(TridiagMatrix), # aa
PDOUBLE, # vv
PDOUBLE, # solution
INT, # nrows
]
libtrisolv.delay_line.restype = None # TODO SPEEDUP W POINTERS!
libtrisolv.delay_line.argtypes = [PDOUBLE, # in_matrix
PINT, # delay1
PINT, # delay2
PINT, # delay1
PINT, # delay1
PDOUBLE, # dev
PDOUBLE, # YZweig
INT, # delay_buffer_length
INT # n
]
这加载正常。
但是,当我调用任何成员函数时,控制永远不会 returns 到 python:
libtrisolv.delay_line(
model.Ybuffer_pointer, model.Zrp_pointer, model.Zrp1_pointer,
model.Zrp2_pointer, model.Zrp3_pointer, model.Dev_pointer,
model.YZweig_pointer, ctypes.c_int(model.YbufferLgt),
ctypes.c_int(model.n + 1))
到 return 大约需要 3 秒,而 在 mac/linux 上 。在 windows 上,我让它 运行 过夜而没有 returning。
这是因为我在 64 位系统上使用 mingw32,还是有其他问题?
成功了。我安装了 Mingw-64
gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.3.0
并用
构建了库
gcc -Wall -shared -m64 -o tridiag.so_windows tridiag.c
现在可以运行了。所以我认为这只是一个愚蠢的架构问题。
我有以下 c 库,tridiag.c
:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define PI 3.14159265358979323846
typedef struct tridiag_matrix{
double *a;
double *b;
double *c;
} Tridiag_M;
inline
double interpl_4(double a,double b,double c,double d,double frac){
return b*(1-frac)+c*frac;
};
double cubic_interpolate( float y0, float y1, float y2, float y3, float mu ) {
double a0, a1, a2, a3, mu2;
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1; //p
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 );
}
inline double cos_interpl(double a,double b,double frac){
double mu2=(1-cos(frac*PI))/2;
return a*(1-mu2)+b*mu2;
};
void solve_tridiagonal(Tridiag_M *t, double *r,double *x,int N) {
int in;
double *cprime=(double*) malloc(N*sizeof(double));
cprime[0] = t->c[0] / t->b[0];
x[0] = r[0] / t->b[0];
/* loop from 1 to N - 1 inclusive */
for (in = 1; in < N; in++) {
double m = 1.0 / (t->b[in] - t->a[in] * cprime[in - 1]);
cprime[in] = t->c[in] * m;
x[in] = (r[in] - t->a[in] * x[in - 1]) * m;
}
/* loop from N - 2 to 0 inclusive, safely testing loop end condition */
for (in = N - 1; in-- > 0; ){
x[in] = x[in] - cprime[in] * x[in + 1]; /*wrong cprime[in] ebasta!*/
}
/* free scratch space */
free(cprime);
}
void delay_line(double *Y, int *delay0,int *delay1,int *delay2,int *delay3,double *dev,double *out,int M,int N){
int i;
for(i=0;i<N;i++){
int k=M*i;
if(dev[i]<1){
out[i]=cubic_interpolate(Y[k+delay0[i]],Y[k+delay1[i]],Y[k+delay2[i]],Y[k+delay3[i]],dev[i]);
}
else{
out[i]=cubic_interpolate(Y[k+(delay0[i]+1)%M],Y[k+(delay1[i]+1)%M],Y[k+(delay2[i]+1)%M],Y[k+(delay3[i]+1)%M],dev[i]-1);
}
}
}
void calculate_g(double *V,double *Y,double *sherad_factor,double *sheraD,double *sheraRho,double *Yzweig,double *omega,double *g,double d_m_factor,const int n){
int i;
g[0]=d_m_factor*V[0];
for(i=1;i<n;i++){
g[i]=sherad_factor[i]*sheraD[i]*V[i]+omega[i]*omega[i]*(Y[i]+sheraRho[i]*Yzweig[i]);
}
}
我正在使用 gcc 4.5.0 / mingw32 在 Windows 7 64 位上编译它。
gcc -shared -m32 -o -Wall tridiag.so_windows tridiag.c
。
这完全退出,没有输出。
在 python 3.5.x 中,我正在加载库:
# load C library
libtrisolv = np.ctypeslib.load_library(tridiagName, resources_root)
# load tridiagonal solver function and defines input
libtrisolv.solve_tridiagonal.restype = None
libtrisolv.solve_tridiagonal.argtypes = [ctypes.POINTER(TridiagMatrix), # aa
PDOUBLE, # vv
PDOUBLE, # solution
INT, # nrows
]
libtrisolv.delay_line.restype = None # TODO SPEEDUP W POINTERS!
libtrisolv.delay_line.argtypes = [PDOUBLE, # in_matrix
PINT, # delay1
PINT, # delay2
PINT, # delay1
PINT, # delay1
PDOUBLE, # dev
PDOUBLE, # YZweig
INT, # delay_buffer_length
INT # n
]
这加载正常。
但是,当我调用任何成员函数时,控制永远不会 returns 到 python:
libtrisolv.delay_line(
model.Ybuffer_pointer, model.Zrp_pointer, model.Zrp1_pointer,
model.Zrp2_pointer, model.Zrp3_pointer, model.Dev_pointer,
model.YZweig_pointer, ctypes.c_int(model.YbufferLgt),
ctypes.c_int(model.n + 1))
到 return 大约需要 3 秒,而 在 mac/linux 上 。在 windows 上,我让它 运行 过夜而没有 returning。
这是因为我在 64 位系统上使用 mingw32,还是有其他问题?
成功了。我安装了 Mingw-64
gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.3.0
并用
构建了库gcc -Wall -shared -m64 -o tridiag.so_windows tridiag.c
现在可以运行了。所以我认为这只是一个愚蠢的架构问题。