Вызов методов C ++ из python

Я застрял с некоторой проблемой при вызове методов C ++ в Python Я получил следующую ссылку в переполнении стека

Но я не использую пакет Boost и swig. Есть ли какой-либо подход в Python может использоваться для вызова этих методов C ++. Я компилирую C ++ как общий объект в Linux и использую в Python 2.7

#include <iostream>
using namespace std;

class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};

class Rectangle: public Polygon {
public:
int area()
{ return width*height; }
};

class Triangle: public Polygon {
public:
int area()
{ return width*height/2; }
};

int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << rect.area() << '\n';
cout << trgl.area() << '\n';
return 0;
}

Могли бы, пожалуйста, руководство для достижения этой цели. Любой фрагмент кода или пример будут высоко оценены.

Заранее спасибо —

0

Решение

Этот ответ только для Python2.x!

Если вы хотите написать расширение C ++, вам сначала нужно скачать python-dev пакет, чтобы получить все необходимые библиотеки и заголовочные файлы (требуется только в Linux)

Самая важная часть в следующем источнике PolygonObject а также PyTypeObject,

PolygonObject

Объект этого класса представляет ваш экземпляр Polygon в Python. Как вы можете видеть, он содержит указатель obj который является вашим оригинальным объектом.

PyTypeObject

https://docs.python.org/2/c-api/type.html#c.PyTypeObject

Структура C объектов, используемая для описания встроенных типов.

Вот как вы можете использовать свой объект Polygon:

import libfoo
po = libfoo.Polygon()
po.set_values(1, 2)

Вот реализация модуля (libfoo.cpp). Этот пример не содержит наследования, но ключевое слово, которое вам нужно найти, это tp_base, Также в оригинальном исходном коде Python есть много примеров, которые могут здесь сильно помочь.

#include <Python.h>

// this is your original class
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};

typedef struct {
PyObject_HEAD
Polygon* obj;
} PolygonObject;

static void
Polygon_dealloc(PolygonObject* self)
{
delete self->obj;
self->ob_type->tp_free((PyObject*)self);
}

static PyObject *
Polygon_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PolygonObject *self;

self = (PolygonObject*)type->tp_alloc(type, 0);
if (self != NULL) {
self->obj = new Polygon;
// do your cleanup here
}

return (PyObject *)self;
}

static PyObject* Polygon_set_values(PolygonObject* self, PyObject *args, PyObject *kwds)
{
int a, b;
const char* kwlist[] = {"a", "b", NULL};

if (! PyArg_ParseTupleAndKeywords(args, kwds, "ii", (char**)kwlist, &a, &b))
return NULL;

self->obj->set_values(a, b);
Py_INCREF(Py_None);
return Py_None;
}

static PyMethodDef Polygon_methods[] = {
{"set_values", (PyCFunction)Polygon_set_values, METH_VARARGS, "set the value"},
{NULL}  /* Sentinel */
};

static PyTypeObject PolygonType = {
PyObject_HEAD_INIT(NULL)
0,                         /*ob_size*/
"mod.Polygon",             /*tp_name*/
sizeof(PolygonObject),           /*tp_basicsize*/
0,                         /*tp_itemsize*/
(destructor)Polygon_dealloc, /*tp_dealloc*/
0,                         /*tp_print*/
0,                         /*tp_getattr*/
0,                         /*tp_setattr*/
0,                         /*tp_compare*/
0,                         /*tp_repr*/
0,                         /*tp_as_number*/
0,                         /*tp_as_sequence*/
0,                         /*tp_as_mapping*/
0,                         /*tp_hash */
0,                         /*tp_call*/
0,                         /*tp_str*/
0,                         /*tp_getattro*/
0,                         /*tp_setattro*/
0,                         /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Polygon class",           /* tp_doc */
0,                         /* tp_traverse */
0,                         /* tp_clear */
0,                         /* tp_richcompare */
0,                         /* tp_weaklistoffset */
0,                         /* tp_iter */
0,                         /* tp_iternext */
Polygon_methods,           /* tp_methods */
0,                         /* tp_members */
0,                         /* tp_getset */
0,                         /* tp_base */
0,                         /* tp_dict */
0,                         /* tp_descr_get */
0,                         /* tp_descr_set */
0,                         /* tp_dictoffset */
0,                         /* tp_init */
0,                         /* tp_alloc */
Polygon_new,               /* tp_new */
};

static PyMethodDef module_methods[] = {
{NULL}  /* Sentinel */
};

PyMODINIT_FUNC
initlibfoo()
{
PyObject* m;

if (PyType_Ready(&PolygonType) < 0)
return;

m = Py_InitModule3("libfoo", module_methods, "Example module that creates an extension type.");
if (m == NULL)
return;

Py_INCREF(&PolygonType);
PyModule_AddObject(m, "Polygon", (PyObject *)&PolygonType);
}

clang ++ -shared -I / usr / include / python2.7 / -fPIC libfoo.cpp -o
libfoo.so -lpython

Вот две дополнительные ссылки, которые дают вам больше информации и более глубокую техническую подготовку по расширению Python.

https://docs.python.org/2/extending/newtypes.html
https://docs.python.org/2/extending/extending.html

1

Другие решения


По вопросам рекламы [email protected]