gpt4 book ai didi

python - cython-将c++类聚合包装

转载 作者:行者123 更新时间:2023-12-02 10:08:43 25 4
gpt4 key购买 nike

我想用Cython为cpp类创建一个包装器。但是这个类聚合了另一个类,我不知道是否还需要为此类创建一个包装器,因为我不想从Python调用第二个类。

有cpp类:

测试类

#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

测试类
#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:\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

最佳答案

我终于设法使它起作用。

无需包装Ocean类,因此无需为其创建.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

测试类
#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

测试类
#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

关于python - cython-将c++类聚合包装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41097214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com