gpt4 book ai didi

python - 如果不是每次都重新编译,numpy ctypes "dynamic module does not define init function"错误

转载 作者:太空狗 更新时间:2023-10-29 21:40:42 25 4
gpt4 key购买 nike

很抱歉还有一个关于动态模块没有定义初始化函数的问题。我确实查看了较早的问题,但没有找到专门针对我的情况的问题。

我有一个 C++ 库,它应该将几个函数导出到 python(比如 extern "C"{} block 中定义的 ~5 个函数)。当我每次导入它时重新编译库时它工作得很好。但是,如果我在不重新编译的情况下导入它,它会给出错误 ImportError: dynamic module does not define init function (initmylib)

重现相同行为(错误)的非常简化的示例如下所示:

文件 mylib.cpp 中的 C++ 库代码

#include <math.h>
// there are some internal C++ functions and classes
// which are not exported, but used in exported functions
extern "C"{
// one of the functions which should be accessible from python
void oscilator( double dt, int n, double * abuff, double * bbuff ){
double a = abuff[0];
double b = bbuff[0];
for (int i=1; i<n; i++){
a = a - b*dt;
b = b + a*dt;
abuff[i] = a;
bbuff[i] = b;
}
}
// there are also other functions but let's keep this example simple
// int initmylib( ){ return 0; } // some junk ... if this makes ctypes happy ?
}

C++ 库 mylib.cpp 的 python warper mylib.py :

import numpy as np
from ctypes import c_int, c_double
import ctypes
import os

name='mylib'
ext='.so' # if compited on linux .so on windows .dll

def recompile(
LFLAGS="",
#FFLAGS="-Og -g -Wall"
FFLAGS="-std=c++11 -O3 -ffast-math -ftree-vectorize"
):
import os
print " ===== COMPILATION OF : "+name+".cpp"
print os.getcwd()
os.system("g++ "+FFLAGS+" -c -fPIC "+name+".cpp -o "+name+".o"+LFLAGS)
os.system("g++ "+FFLAGS+" -shared -Wl,-soname,"+name+ext+" -o "+name+ext+" "+name+".o"+LFLAGS)

# this will recompile the library if somebody delete it
if not os.path.exists("./"+name+ext ):
recompile()

lib = ctypes.CDLL("./"+name+ext )

array1d = np.ctypeslib.ndpointer(dtype=np.double, ndim=1, flags='CONTIGUOUS')

# void oscilator( double dt, int n, double * abuff, double * bbuff )
lib.oscilator.argtypes = [ c_double, c_int, array1d, array1d ]
lib.oscilator.restype = None
def oscilator( dt, a, b ):
n = len(a)
lib.oscilator( dt, n, a, b )

导入mylib 的python 程序test.py

import os
from pylab import *
from basUtils import *

# this will delete all compiled files of the library to force recompilation
def makeclean( ):
[ os.remove(f) for f in os.listdir(".") if f.endswith(".so") ]
[ os.remove(f) for f in os.listdir(".") if f.endswith(".o") ]
[ os.remove(f) for f in os.listdir(".") if f.endswith(".pyc") ]

# if I do makeclean() every time it works, if I do not it does not
#makeclean( )

import mylib

a=zeros(100)
b=zeros(100)
a[0] = 1

mylib.oscilator( 0.1, a, b )

plot( a )
plot( b )

show()

我还试图通过添加一些 int initmylib( ){ return 0; 来让 ctypes 满意} 函数到 mylib.cpp 中,如您在上面的代码中所见。然而这会产生错误 SystemError: dynamic module not initialized properly

我编译 cos_doubles 的例子时没有这个问题来自 scipy 讲义。但是,此示例仅在我只想导入一个与库名称同名的函数时才有效。我想要更通用的东西。

最佳答案

尝试运行 import imp;打印 imp.find_module('mylib')[1]。你对它选择 mylib.so 而不是 mylib.py 感到惊讶吗?解释器期望 mylib.so 是一个扩展模块,对于 CPython 2.x,它应该定义一个名为 initmylib 的初始化函数。为避免意外导入共享库,请将名称更改为类似 _mylib.so 或 mylib.1.0.so 的名称,或者将文件保存在 sys.path 之外的目录中。

请注意,Windows 扩展模块是 DLL,但扩展名为 .pyd 而不是 .dll。所以 import mylib 不会尝试加载 mylib.dll。

关于python - 如果不是每次都重新编译,numpy ctypes "dynamic module does not define init function"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30455178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com