本文介绍了numpy ctypes“动态模块未定义初始化函数".如果每次都不重新编译,则报错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,还有关于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“动态模块未定义初始化函数".如果每次都不重新编译,则报错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!