I build a .so C++ library using g++ and -fPIC (using eclipse).
Still using eclipse, I linked this library and used it in another C++ project without any problem.
But, When I build a Cython project with that same lib to generate a python extension, using :
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" being the mentioned library, the build is fine too : I get my cyelp.so library.
The problem occurs when I get a specific class from the library at runtime from python side script :
Here is my cython class (that inherits from a ALabSimulationTime:LabSimulationTime class implementing the method FireEvent() - method which is declared as "pure virtual" in 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()
And here, my python loading attempt :
from cyelp import PyLabSimulatorTime;
Finally, here's the error message :
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
The fact is that it doesn't happen if I redefine the "FireEvent()" method in ALabSimulatorTime class from the header file :
virtual void FireEvent() {};
But does happen if I redefine the method from the ".cpp" file :
void ALabSimulatorTime::FireEvent()
{
//...
}
Note : Everything works well if I turn FireEvent to "non-pure" from the base class "LabSimulatorTime".
I could, of course, try to be more specific, but may be some of you already has an idea about what is going on.
Thanks a lot