Cython-包装CPP类,汇总另一个
cython - wrap a cpp class aggregating an other
我想用Cython创建一个CPP类包装器。但是这个课程汇总了另一个课程,我不知道我是否还需要为此课程创建一个包装器,因为我不想从Python打电话。
有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
我只想包装测试课,这是我尝试的:
Ocean.pxd
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)是正确的方法吗?(当我编译时,我会收到以下错误,但我不明白错误。)
C:MinGWbingcc.exe -mdll -O -Wall -IC:Python27include -IC:Python27PC -c testclass.cpp -o buildtemp.win32-2.7Releasetestclass.o
writing buildtemp.win32-2.7Releasetest.def
C:MinGWbing++.exe -shared -s buildtemp.win32-2.7Releasetest.o buildtemp.win32-2.7Releasetestclass.o buildtemp.win32-2.7Releasetest.def -LC:Python27libs -LC:Python27PCbuild -LC:Python27PCVS9.0 -lpython27 -lmsv
cr90 -o E: 0-ProjetsInWaveCouplagePYWC++test3test.pyd
buildtemp.win32-2.7Releasetestclass.o:testclass.cpp:(.text+0x97): undefined reference to `Ocean::~Ocean()'
buildtemp.win32-2.7Releasetestclass.o:testclass.cpp:(.text+0xa3): undefined reference to `Ocean::~Ocean()'
buildtemp.win32-2.7Releasetestclass.o:testclass.cpp:(.text+0xe4): undefined reference to `Ocean::Ocean()'
buildtemp.win32-2.7Releasetestclass.o:testclass.cpp:(.text+0xfa): undefined reference to `Ocean::Ocean()'
buildtemp.win32-2.7Releasetestclass.o:testclass.cpp:(.text+0x11a): undefined reference to `Ocean::~Ocean()'
buildtemp.win32-2.7Releasetestclass.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
我最终设法使它起作用。
无需包装海洋类,因此为其创建.pxd
文件。但是在setup.py
中,包括所有.cpp
依赖关系很重要。
如前所述,在标题文件中添加guard也很重要。
所以这是一个工作代码(用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;
}
test.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
setup.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
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将 N-arg 函数包装到另一个函数中
- 如何包装一个函数以适应另一个函数的所需类型
- 如何在 C 中包装C++具有参数的类方法或返回另一个C++类的实例?
- Cython-包装CPP类,汇总另一个
- 当包含在另一个向量中时,如何使用矢量包装程序类
- 使用SWIG包装C 类,该类调用另一个对象成员函数
- 从 Win32 包装器 WndProc 调用另一个类中的函数
- 将 c++11 std::function 包装在另一个 std::function 中
- 如何在Cython中从另一个包装对象返回包装的c++对象
- JNI包装另一个库
- 如何包装另一个类(c++)
- 自定义迭代器包装另一个迭代器:迭代到底层的end迭代器而不进行检查
- 你能把一个异常继承层次结构包装到另一个吗?——或者,另一种干净的处理方式
- 将BOOST_LOG_SEV宏包装到另一个宏
- 为另一个程序包装代码/类
- Cython包装使用另一个库的类