问题描述
很抱歉,还有关于dynamic module does not define init function
的其他问题.我确实遇到了一些较早的问题,但没有找到一个能完全满足我的情况的问题.
sorry for yet an other question about dynamic module does not define init function
. I did go through older questions but I didn't find one which adress my case specifically enought.
我有一个C ++库,该库应该将多个函数导出到python(如extern "C" {}
块中定义的〜5个函数).每次导入库时,只要重新编译该库,它就可以正常工作.但是,如果我不重新编译就将其导入,则会出现错误ImportError: dynamic module does not define init function (initmylib)
I have a C++ library which should export several functions to python ( like ~5 functions defined in extern "C" {}
block ). It works just fine when I recompile the library each time I import it. However, if I import it without recompilation it gives error ImportError: dynamic module does not define init function (initmylib)
非常简单的示例再现了相同的行为(错误),如下所示:
The very simplified example which reproduce the same behaviour (error) looks like this:
文件mylib.cpp
#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
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()
我还试图通过在mylib.cpp
中添加一些int initmylib( ){ return 0; }
函数来使ctypes满意,如上面的代码所示.但这会产生错误SystemError: dynamic module not initialized properly
I was also trying to make ctypes happy by adding some int initmylib( ){ return 0; }
function into mylib.cpp
as you can see in the code above. however this will produce error SystemError: dynamic module not initialized properly
当我编译 cos_doubles 从scipy讲义中摘录.但是,此示例仅在我只想导入一个与库名称相同的函数时才有效.我想要更一般的东西.
I don't have this issue when I compile example of cos_doubles from scipy lecture notes. However, this example works only If I want to import just one function with the same name as the name of the library. I want something more general.
推荐答案
尝试运行import imp; print imp.find_module('mylib')[1]
.您对它选择mylib.so而不是mylib.py感到惊讶吗?解释器希望mylib.so是一个扩展模块,对于CPython 2.x,它应该定义一个名为initmylib
的初始化函数.为避免意外尝试导入共享库,请将名称更改为_mylib.so或mylib.1.0.so之类的名称-或仅将文件保存在sys.path
不在的目录中.
Try running import imp; print imp.find_module('mylib')[1]
. Are you surprised that it picks mylib.so instead of mylib.py? The interpreter expects mylib.so to be an extension module, which for CPython 2.x should define an initialization function named initmylib
. To avoid accidentally trying to import the shared library, either change the name to something like _mylib.so or mylib.1.0.so -- or just save the file in a directory that's not in sys.path
.
请注意,Windows扩展模块是DLL,但扩展名为.pyd而不是.dll.因此import mylib
不会尝试加载mylib.dll.
Note that Windows extension modules are DLLs, but with a .pyd extension instead of .dll. So import mylib
won't try to load mylib.dll.
这篇关于numpy ctypes“动态模块未定义初始化函数".如果每次都不重新编译,则报错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!