3

g ++と-fPICを使用して(Eclipseを使用して).soC++ライブラリを構築します。

まだEclipseを使用しているので、このライブラリをリンクして、別のC++プロジェクトで問題なく使用しました。

しかし、同じlibを使用して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クラスです(メソッドFireEvent()を実装するALabSimulationTime:LabSimulationTimeクラスから継承します-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

実際には、ヘッダーファイルからALabSimulatorTimeクラスの「FireEvent()」メソッドを再定義しても発生しません。

virtual void FireEvent() {};

しかし、「。cpp」ファイルからメソッドを再定義すると、実際に発生します。

void ALabSimulatorTime::FireEvent()
{
    //...
}

注:FireEventを基本クラス「LabSimulatorTime」から「非純粋」にすると、すべてがうまく機能します。

もちろん、もっと具体的にしようとすることもできますが、何が起こっているのかについてすでに考えている人もいるかもしれません。

どうもありがとう

4

0 に答える 0