Why do I get this error "ImportError: dlopen(...): Symbol not found"? when I import my library on python
Why do I get this error "ImportError: dlopen(...): Symbol not found"? when I import my library on python
我一直在尝试在我的 python 项目中使用一些 C 代码与 CFFI,但是当我尝试构建然后导入我构建的库 import _chebyshev_cffi
,我收到以下错误:
ImportError: dlopen(/Users/Username/Documents/code project/_chebyshev_cffi.cpython-35m-darwin.so, 2): Symbol not found: _elementary_clenshaw_step_real
Referenced from: /Users/Username/Documents/code project/_chebyshev_cffi.cpython-35m-darwin.so
Expected in: flat namespace
我不确定这里出了什么问题,我一直无法找到有关此错误的信息,如果您能提供帮助,我将不胜感激。
我正在为 python 使用 MacOS 和 anaconda 发行版,cffi 似乎已正确安装。
编辑:我可能应该补充一点,我实际期望的函数前面不应该有下划线。它应该是 ”
elementary_clenshaw_step_real
而不是 _elementary_clenshaw_step_real
。
这是源代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 3 17:00:38 2019
@author: anonymous
"""
from cffi import FFI
ffibuilder = FFI()
ffibuilder.cdef("void elementary_clenshaw_step_real(const int dim_x, const char * restrict boundary_condition, const double * restrict wfc, const double * restrict psi, double * restrict psi_old, const double c_coef, const double one_or_two, const int add_real, const double tunneling, const double * restrict disorder);")
ffibuilder.cdef("void chebyshev_clenshaw_real(const int dim_x, const int max_order, const char * restrict boundary_condition, double * wfc, double * psi, double * psi_old, const double tunneling, const double * disorder, const double *tab_coef, const double g_times_delta_t, const double e0_times_delta_t);")
ffibuilder.set_source("_chebyshev_cffi",
r"""
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __ICC
#include <mathimf.h>
#else
#include <math.h>
#endif
#include <complex.h>
void __inline elementary_clenshaw_step_real(const int dim_x, const char * restrict boundary_condition, const double * restrict wfc, const double * restrict psi, double * restrict psi_old, const double c_coef, const double one_or_two, const int add_real, const double tunneling, const double * restrict disorder)
{
int i;
if (add_real) {
if (strcmp(boundary_condition,"periodic") == 0) {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*(psi[1]+psi[dim_x-1]))+c_coef*wfc[0]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*(psi[dim_x+1]+psi[2*dim_x-1]))+c_coef*wfc[dim_x]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*(psi[0]+psi[dim_x-2]))+c_coef*wfc[dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*(psi[dim_x]+psi[2*dim_x-2]))+c_coef*wfc[2*dim_x-1]-psi_old[2*dim_x-1];
} else {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*psi[1])+c_coef*wfc[0]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*psi[dim_x+1])+c_coef*wfc[dim_x]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*psi[dim_x-2])+c_coef*wfc[dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*psi[2*dim_x-2])+c_coef*wfc[2*dim_x-1]-psi_old[2*dim_x-1];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=1;i<dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i]-psi_old[i];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=dim_x+1;i<2*dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i-dim_x]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i]-psi_old[i];
}
} else {
if (strcmp(boundary_condition,"periodic") == 0) {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*(psi[1]+psi[dim_x-1]))-c_coef*wfc[dim_x]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*(psi[dim_x+1]+psi[2*dim_x-1]))+c_coef*wfc[0]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*(psi[0]+psi[dim_x-2]))-c_coef*wfc[2*dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*(psi[dim_x]+psi[2*dim_x-2]))+c_coef*wfc[dim_x-1]-psi_old[2*dim_x-1];
} else {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*psi[1])-c_coef*wfc[dim_x]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*psi[dim_x+1])+c_coef*wfc[0]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*psi[dim_x-2])-c_coef*wfc[2*dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*psi[2*dim_x-2])+c_coef*wfc[dim_x-1]-psi_old[2*dim_x-1];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=1;i<dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))-c_coef*wfc[i+dim_x]-psi_old[i];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=dim_x+1;i<2*dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i-dim_x]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i-dim_x]-psi_old[i];
}
}
return;
}
void chebyshev_clenshaw_real(const int dim_x, const int max_order, const char * restrict boundary_condition, double * restrict wfc, double * restrict psi, double * restrict psi_old, const double tunneling, const double * restrict disorder, const double * restrict tab_coef, const double g_times_delta_t, const double e0_times_delta_t)
{
int i, order;
double argument;
double cos_phase;
double sin_phase;
for (i=0;i<2*dim_x;i++) {
psi[i] = tab_coef[max_order] * wfc[i];
}
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi, psi_old, tab_coef[max_order-1], 2.0, 0, tunneling, disorder);
// WARNING: max_order MUST be an even number, otherwise disaster guaranteed
for (order=max_order-2;order>1;order-=2) {
// printf("order = %d %d %lf %lf\n",order,(order+1)%2,tab_coef[order],tunneling);
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi_old, psi, tab_coef[order], 2.0, 1, tunneling, disorder);
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi, psi_old, tab_coef[order-1], 2.0, 0, tunneling, disorder);
}
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi_old, psi, tab_coef[0], 1.0, 1, tunneling, disorder);
// apply nonlinear shift
if (g_times_delta_t==0.0) {
cos_phase=cos(e0_times_delta_t);
sin_phase=sin(e0_times_delta_t);
#ifdef __clang__
#else
#pragma GCC ivdep
#endif
for (i=0;i<dim_x;i++) {
wfc[i] = psi[i]*cos_phase+psi[i+dim_x]*sin_phase;
wfc[i+dim_x] = psi[i+dim_x]*cos_phase-psi[i]*sin_phase;
}
} else {
#ifdef __clang__
#else
#pragma GCC ivdep
#endif
for (i=0;i<dim_x;i++) {
argument = e0_times_delta_t+g_times_delta_t*(psi[i]*psi[i]+psi[i+dim_x]*psi[i+dim_x]);
wfc[i] = psi[i]*cos(argument)+psi[i+dim_x]*sin(argument);
wfc[i+dim_x] = psi[i+dim_x]*cos(argument)-psi[i]*sin(argument);
}
}
return;
}
""")
if __name__ == "__main__":
ffibuilder.compile(verbose=True)
问题是用 void __inline
声明函数。我不完全确定为什么,但它似乎同时使该功能“强制内联”(因此编译后没有主体)和“非静态”(因此带有外部符号)。这可能是导致问题的原因。如果您删除 __inline
或在 void __inline
前面添加 static
,那么一切都会按预期进行。如果你问一个关于它的纯 C 问题,你可能会得到更多信息。
我一直在尝试在我的 python 项目中使用一些 C 代码与 CFFI,但是当我尝试构建然后导入我构建的库 import _chebyshev_cffi
,我收到以下错误:
ImportError: dlopen(/Users/Username/Documents/code project/_chebyshev_cffi.cpython-35m-darwin.so, 2): Symbol not found: _elementary_clenshaw_step_real
Referenced from: /Users/Username/Documents/code project/_chebyshev_cffi.cpython-35m-darwin.so
Expected in: flat namespace
我不确定这里出了什么问题,我一直无法找到有关此错误的信息,如果您能提供帮助,我将不胜感激。 我正在为 python 使用 MacOS 和 anaconda 发行版,cffi 似乎已正确安装。
编辑:我可能应该补充一点,我实际期望的函数前面不应该有下划线。它应该是 ”
elementary_clenshaw_step_real
而不是 _elementary_clenshaw_step_real
。
这是源代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 3 17:00:38 2019
@author: anonymous
"""
from cffi import FFI
ffibuilder = FFI()
ffibuilder.cdef("void elementary_clenshaw_step_real(const int dim_x, const char * restrict boundary_condition, const double * restrict wfc, const double * restrict psi, double * restrict psi_old, const double c_coef, const double one_or_two, const int add_real, const double tunneling, const double * restrict disorder);")
ffibuilder.cdef("void chebyshev_clenshaw_real(const int dim_x, const int max_order, const char * restrict boundary_condition, double * wfc, double * psi, double * psi_old, const double tunneling, const double * disorder, const double *tab_coef, const double g_times_delta_t, const double e0_times_delta_t);")
ffibuilder.set_source("_chebyshev_cffi",
r"""
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __ICC
#include <mathimf.h>
#else
#include <math.h>
#endif
#include <complex.h>
void __inline elementary_clenshaw_step_real(const int dim_x, const char * restrict boundary_condition, const double * restrict wfc, const double * restrict psi, double * restrict psi_old, const double c_coef, const double one_or_two, const int add_real, const double tunneling, const double * restrict disorder)
{
int i;
if (add_real) {
if (strcmp(boundary_condition,"periodic") == 0) {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*(psi[1]+psi[dim_x-1]))+c_coef*wfc[0]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*(psi[dim_x+1]+psi[2*dim_x-1]))+c_coef*wfc[dim_x]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*(psi[0]+psi[dim_x-2]))+c_coef*wfc[dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*(psi[dim_x]+psi[2*dim_x-2]))+c_coef*wfc[2*dim_x-1]-psi_old[2*dim_x-1];
} else {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*psi[1])+c_coef*wfc[0]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*psi[dim_x+1])+c_coef*wfc[dim_x]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*psi[dim_x-2])+c_coef*wfc[dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*psi[2*dim_x-2])+c_coef*wfc[2*dim_x-1]-psi_old[2*dim_x-1];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=1;i<dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i]-psi_old[i];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=dim_x+1;i<2*dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i-dim_x]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i]-psi_old[i];
}
} else {
if (strcmp(boundary_condition,"periodic") == 0) {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*(psi[1]+psi[dim_x-1]))-c_coef*wfc[dim_x]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*(psi[dim_x+1]+psi[2*dim_x-1]))+c_coef*wfc[0]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*(psi[0]+psi[dim_x-2]))-c_coef*wfc[2*dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*(psi[dim_x]+psi[2*dim_x-2]))+c_coef*wfc[dim_x-1]-psi_old[2*dim_x-1];
} else {
psi_old[0]=one_or_two*(disorder[0]*psi[0]-tunneling*psi[1])-c_coef*wfc[dim_x]-psi_old[0];
psi_old[dim_x]=one_or_two*(disorder[0]*psi[dim_x]-tunneling*psi[dim_x+1])+c_coef*wfc[0]-psi_old[dim_x];
psi_old[dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[dim_x-1]-tunneling*psi[dim_x-2])-c_coef*wfc[2*dim_x-1]-psi_old[dim_x-1] ;
psi_old[2*dim_x-1]=one_or_two*(disorder[dim_x-1]*psi[2*dim_x-1]-tunneling*psi[2*dim_x-2])+c_coef*wfc[dim_x-1]-psi_old[2*dim_x-1];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=1;i<dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))-c_coef*wfc[i+dim_x]-psi_old[i];
}
#ifdef __clang__
#else
#pragma GCC ivdep
#ifdef __ICC
#pragma distribute_point
#endif
#endif
for (i=dim_x+1;i<2*dim_x-1;i++) {
psi_old[i]=one_or_two*(disorder[i-dim_x]*psi[i]-tunneling*(psi[i+1]+psi[i-1]))+c_coef*wfc[i-dim_x]-psi_old[i];
}
}
return;
}
void chebyshev_clenshaw_real(const int dim_x, const int max_order, const char * restrict boundary_condition, double * restrict wfc, double * restrict psi, double * restrict psi_old, const double tunneling, const double * restrict disorder, const double * restrict tab_coef, const double g_times_delta_t, const double e0_times_delta_t)
{
int i, order;
double argument;
double cos_phase;
double sin_phase;
for (i=0;i<2*dim_x;i++) {
psi[i] = tab_coef[max_order] * wfc[i];
}
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi, psi_old, tab_coef[max_order-1], 2.0, 0, tunneling, disorder);
// WARNING: max_order MUST be an even number, otherwise disaster guaranteed
for (order=max_order-2;order>1;order-=2) {
// printf("order = %d %d %lf %lf\n",order,(order+1)%2,tab_coef[order],tunneling);
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi_old, psi, tab_coef[order], 2.0, 1, tunneling, disorder);
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi, psi_old, tab_coef[order-1], 2.0, 0, tunneling, disorder);
}
elementary_clenshaw_step_real(dim_x, boundary_condition, wfc, psi_old, psi, tab_coef[0], 1.0, 1, tunneling, disorder);
// apply nonlinear shift
if (g_times_delta_t==0.0) {
cos_phase=cos(e0_times_delta_t);
sin_phase=sin(e0_times_delta_t);
#ifdef __clang__
#else
#pragma GCC ivdep
#endif
for (i=0;i<dim_x;i++) {
wfc[i] = psi[i]*cos_phase+psi[i+dim_x]*sin_phase;
wfc[i+dim_x] = psi[i+dim_x]*cos_phase-psi[i]*sin_phase;
}
} else {
#ifdef __clang__
#else
#pragma GCC ivdep
#endif
for (i=0;i<dim_x;i++) {
argument = e0_times_delta_t+g_times_delta_t*(psi[i]*psi[i]+psi[i+dim_x]*psi[i+dim_x]);
wfc[i] = psi[i]*cos(argument)+psi[i+dim_x]*sin(argument);
wfc[i+dim_x] = psi[i+dim_x]*cos(argument)-psi[i]*sin(argument);
}
}
return;
}
""")
if __name__ == "__main__":
ffibuilder.compile(verbose=True)
问题是用 void __inline
声明函数。我不完全确定为什么,但它似乎同时使该功能“强制内联”(因此编译后没有主体)和“非静态”(因此带有外部符号)。这可能是导致问题的原因。如果您删除 __inline
或在 void __inline
前面添加 static
,那么一切都会按预期进行。如果你问一个关于它的纯 C 问题,你可能会得到更多信息。