извините за еще один вопрос о dynamic module does not define init function
. Я перешел к более старым вопросам, но я не нашел тот, который достаточно подробно остановил мой случай.numpy ctypes «динамический модуль не определяет функцию функции init», если не перекомпилирован каждый раз
У меня есть библиотека C++, которая должна экспортировать несколько функций в python (например, ~ 5 функций, определенных в блоке extern "C" {}
). Он отлично работает, когда я перекомпилирую библиотеку каждый раз, когда я ее импортирую. Тем не менее, если я импортировать его без повторной компиляции он дает ошибку ImportError: dynamic module does not define init function (initmylib)
Очень упрощенный пример, который воспроизводят такое же поведение (ошибка) выглядит следующим образом:
C++ библиотеки кода в файле 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 ?
}
питона сновальщик mylib.py
из C++ библиотеки mylib.cpp
:
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)
питон про грамм test.py
, который импортирует 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()
Я также пытался сделать ctypes счастливым, добавив некоторые int initmylib(){ return 0; }
функцию в mylib.cpp
, как вы можете видеть в коде выше. однако это приведет к ошибке SystemError: dynamic module not initialized properly
У меня нет этой проблемы, когда я компилирую пример cos_doubles из заметок лекции. Однако этот пример работает только в том случае, если я хочу импортировать только одну функцию с тем же именем, что и имя библиотеки. Я хочу нечто более общее.
eryksun> ах, спасибо, вы правы, имя файла скомпилированной библиотеки является проблемой. С 'lib_mylib.so' отлично работает. Вы хотите, чтобы regyer ответ, чтобы я мог принять его и закрыть вопрос? –