Я создаю библиотеку .so C ++, используя g ++ и -fPIC (используя eclipse).
Все еще используя eclipse, я связал эту библиотеку и использовал ее в другом проекте C ++ без каких-либо проблем.
Но,
Когда я собираю проект Cython с той же самой библиотекой для генерации расширения Python, используя:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
Extension("cyelp",
sources=["cyelp.pyx", \
"adapter/ATestClass.cpp", \
"adapter/ALabSimulatorTime.cpp", \
],
libraries=["elp"],
language="c++",
)
]
)
«libelp.so», являющаяся упомянутой библиотекой, сборка тоже в порядке: я получаю свою библиотеку cyelp.so.
Проблема возникает, когда я получаю определенный класс из библиотеки во время выполнения из скрипта на стороне Python:
Вот мой класс Cython (который наследуется от класса ALabSimulationTime: LabSimulationTime, реализующего метод FireEvent () — метод, который объявлен как «чисто виртуальный» в LabSimulationTime):
cimport cpython.ref as cpy_ref
cdef extern from "adapter/ALabSimulatorTime.h" namespace "elps" :
cdef cppclass ALabSimulatorTime:
ALabSimulatorTime(cpy_ref.PyObject *obj)
# Virtual overridable
void ResetTime()
double TimeStep()
void FireEvent()
void StepSimulation()
int EndSimulation()
void RunSimulation()
# Others
void UpdateEventsRate(double rate)
void SetEndTime(double end_time)
void SetOutputTimeStep(double out_time_step)
double GetTime()
int GetNbFiredEvents()
void SetTime(double time)cdef class PyLabSimulatorTime:
cdef ALabSimulatorTime* thisptr
def __cinit__(self):
self.thisptr = new ALabSimulatorTime(<cpy_ref.PyObject*>self)
def __dealloc__(self):
if self.thisptr:
del self.thisptr
cpdef ResetTime(self):
self.thisptr.ResetTime()
cpdef double TimeStep(self):
return self.thisptr.TimeStep()
И вот, моя попытка загрузки Python:
from cyelp import PyLabSimulatorTime;
Наконец, вот сообщение об ошибке:
Traceback (most recent call last):
File "src/Spacial/BdmLsim2.py", line 1, in <module>
from cyelp import PyLabSimulatorTime;
ImportError: setup/cyelp.so: undefined symbol: _ZN4elps16LabSimulatorTime9FireEventEv
Дело в том, что этого не произойдет, если я переопределю метод «FireEvent ()» в классе ALabSimulatorTime из файла заголовка:
virtual void FireEvent() {};
Но произойдет, если я переопределю метод из файла «.cpp»:
void ALabSimulatorTime::FireEvent()
{
//...
}
Примечание: все работает хорошо, если я включаю FireEvent в «неочищенный» из базового класса «LabSimulatorTime».
Я мог бы, конечно, попытаться быть более конкретным, но, возможно, некоторые из вас уже имеют представление о том, что происходит.
большое спасибо
Задача ещё не решена.
Других решений пока нет …