2016-12-12 4 views
0

。しかし、このクラスは他のクラスを集約しています。私はPythonからこの2番目のクラスを呼びたくないので、このクラスのラッパーも作成する必要があるかどうかわかりません。cython - 集約cppのクラスをラップし、他の私はCythonとcppのクラスのラッパーを作成したいと思い

cppのクラスがあります。

testclass.hpp

#ifndef TESTCLASS_H 
#define TESTCLASS_H 
#include "ocean.hpp" 

class TestClass { 
    private: 
     Ocean _ocean; 

    public: 
     int x, y; 
     TestClass(); 
     ~TestClass(); 
     int Multiply(int a, int b); 
}; 
#endif 

testclass.cpp

#include "testclass.hpp" 
TestClass::TestClass() 
{ 
    x = 5; 
    y = 1; 
    _ocean = Ocean(); 
} 

TestClass::~TestClass() 
{ 
    std::cout << "Calling destructor" << std::endl; 
} 

int TestClass::Multiply(int a, int b) 
{ 
    return a*b; 
} 

ocean.hpp

#ifndef OCEAN_H 
#define OCEAN_H 
class Ocean { 
    public: 
     double _depth; 
     double _rho; 

     Ocean(); 
     virtual ~Ocean(); 
     void setwaterdepth(double d); 
}; 
#endif 

私はラップしたいと思いますが、テストクラスのみ、T

cdef extern from "ocean.hpp": 
cdef cppclass Ocean: 
    Ocean() 

test.pyx

from ocean cimport Ocean 

cdef extern from "testclass.hpp": 
    cdef cppclass TestClass: 
     TestClass() 
     int x 
     int y 
     int Multiply(int a, int b) 

cdef class pyTestClass: 
    cdef TestClass* thisptr # hold a C++ instance 

    def __cinit__(self): 
     self.thisptr = new TestClass() 

    def __dealloc__(self): 
     del self.thisptr 

    def Multiply(self, a, b): 
     return self.thisptr.Multiply(a, b) 

setup.py

from distutils.core import setup, Extension 
from Cython.Build import cythonize 

ext = Extension("test", 
       sources=["test.pyx", "testclass.cpp"], 
       language="c++") 

setup(name="test", 
     ext_modules=cythonize(ext)) 

Q1)は、それを行うための正しい方法ですocean.pxd:彼は、私が試したものです? (私はこれをコンパイルすると、私は次のエラーを取得すると、私はエラーを理解していない。)

C:\MinGW\bin\gcc.exe -mdll -O -Wall -IC:\Python27\include -IC:\Python27\PC -c testclass.cpp -o build\temp.win32-2.7\Release\testclass.o 
writing build\temp.win32-2.7\Release\test.def 
C:\MinGW\bin\g++.exe -shared -s build\temp.win32-2.7\Release\test.o build\temp.win32-2.7\Release\testclass.o build\temp.win32-2.7\Release\test.def -LC:\Python27\libs -LC:\Python27\PCbuild -LC:\Python27\PC\VS9.0 -lpython27 -lmsv 
cr90 -o E:\00-Projets\InWave\Couplage\PYW\C++\test3\test.pyd 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0x97): undefined reference to `Ocean::~Ocean()' 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0xa3): undefined reference to `Ocean::~Ocean()' 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0xe4): undefined reference to `Ocean::Ocean()' 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0xfa): undefined reference to `Ocean::Ocean()' 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0x11a): undefined reference to `Ocean::~Ocean()' 
build\temp.win32-2.7\Release\testclass.o:testclass.cpp:(.text+0x196): undefined reference to `Ocean::~Ocean()' 
collect2.exe: error: ld returned 1 exit status 
error: command 'C:\\MinGW\\bin\\g++.exe' failed with exit status 1 
+0

申し訳ありません!エラーログは間違っていたので編集しました。 :が追加されましたが、生成されたtest.cppファイルにはまだエラーがあります。 –

+0

エラーは変わりません。 –

+0

私はそれを試して、私はセットアップからのエラーがあります。私は 'testclass.cpp'に' iostream'を含めることを忘れてしまい、あなたは 'Ocean'の実装を提供しません。なぜあなたは海から来るのですか?私はcythonについて何も知らないことに注意してください。 – Stargateur

答えて

0

私は最終的にそれを動作させるために管理します。

オーシャンクラスをラップするために、結果としてそれのため.pxdファイルを作成する必要はありません。 しかしsetup.pyで、すべての.cpp依存関係を含めることが重要です。

前述のコメントと同様に、ヘッダーファイルにインクルードガードを追加することも重要です。だからここ

は(python setup.py build_ext --inplaceでコンパイルされた)作業コード

ocean.hpp

#ifndef OCEAN_H 
#define OCEAN_H 

class Ocean { 
    public: 
     double _depth; 
     double _rho; 

     Ocean(); 
     virtual ~Ocean(); 
     void setwaterdepth(double d); 
}; 

#endif 

testclass.hpp

#ifndef TESTCLASS_H 
#define TESTCLASS_H 
#include "ocean.hpp" 

class TestClass { 
    private: 
     Ocean _ocean; 

    public: 
     int x, y; 
     TestClass(); 
     virtual ~TestClass(); 
     int Multiply(int a, int b); 
     void _set_x(int x); 
}; 

#endif 

testclass.cpp

#include <iostream> 
#include "testclass.hpp" 
#include "ocean.hpp" 

TestClass::TestClass() 
{ 
    x = 5; 
    y = 1; 
    _ocean = Ocean(); 
    std::cout << "Calling constructor" << std::endl; 
} 

TestClass::~TestClass() 
{ 
    std::cout << "Calling destructor" << std::endl; 
} 

int TestClass::Multiply(int a, int b) 
{ 
    return a*b; 
} 

void TestClass::_set_x(int new_x) 
{ 
    x = new_x; 
} 

テストです.pyx

cdef extern from "testclass.hpp": 
    cdef cppclass TestClass: 
     TestClass() 
     int x 
     int y 
     int Multiply(int a, int b) 

cdef class pyTestClass: 
    cdef TestClass* thisptr # hold a C++ instance 

    def __cinit__(self): 
     self.thisptr = new TestClass() 

    def __dealloc__(self): 
     del self.thisptr 

    def Multiply(self, a, b): 
     return self.thisptr.Multiply(a, b) 

    property y: 

     # Here we use a property to expose the public member 
     # y of TestClass to Python 

     def __get__(pyTestClass self): 
      return self.thisptr.y 

     def __set__(pyTestClass self, value): 
      self.thisptr.y = <int> value 

セットアップ。ラップ

のPY

from distutils.core import setup, Extension 
from Cython.Build import cythonize 

ext = Extension("test", 
      sources=["test.pyx", "testclass.cpp", "ocean.cpp"], 
      language="c++") 

setup(name="test", ext_modules=cythonize(ext)) 

テスト

import test as wrapper 

T = wrapper.pyTestClass() 
print T.Multiply(3, 5) 
print T.y 
T.y = 3 
print T.y 

出力

Calling ocean constructor 
Calling ocean constructor 
Calling ocean destructor 
Calling constructor 
15 
1 
3 
Calling destructor 
Calling ocean destructor 
関連する問題