在Python调用复杂的C ++函数(Linux)的(Calling complicated C++

2019-10-18 13:57发布

我在C ++源代码的一些功能,声明如下:

extern "C" {
    int32_t comp_ip_long(const std::vector<EachColumn>& in, std::vector<EachColumn>& out);
}

C ++代码被编译成xxx.so(Linux共享对象),我想调用在Python的功能。 请注意,我不能修改的C ++代码,所以像boost::python是不可访问,。

我试过ctypes.CDLL,但我不知道如何通过复杂的参数xxx.so?

PS:

我已经给了一些功能。所以(与上面的参数类型,但函数的名称未知),函数名和参数是由用户输入。

Answer 1:

我认为,你需要声明的助手胶水功能extern "C"来构建(即初始化),并填写您std::vector<EachColumn>并让这些从Python中叫辅助功能。

也许

typedef std::vector<EachColumn> columnvect_t;
extern "C" columnvect_t *new_vect() 
    { return new columnvect_t; };
extern "C" void del_vect(columnvect_t*vec) 
   { delete vec; };
extern "C" void pushback_vect(columnvect_t* vec, EachColumn* col) 
   { vec->push_back(*col); };

同样地为您EachColumn类。

也许你需要链接到C ++库胶水图书馆dlopen被Python -ed

基本上,Python是多个C比C ++友好的(所以你需要做C ++胶水代码感觉像C为Python)友好。 要小心,没有C ++异常抛出跨越Python解释器(所以赶上所有的人里面的胶水功能)

如果C或C ++代码是巨大的,你可以考虑定制GCC在产生这种胶水代码也许帮助,无论是与MELT或D.Malcom的GCC蟒蛇插件 。 但是,这需要时间。



Answer 2:

多做一些工作,但也许值得从长远来看是使用Boost.Python的

例如,从升压文档采取:

下面的C / C ++的传统,让我们先从“你好,世界”。 C ++函数:

char const* greet()
{
    return "hello, world";
}

可以通过编写Boost.Python的包装暴露到Python:

#include <boost/python.hpp>

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

而已。 我们就大功告成了。 现在,我们可以建立这个作为一个共享库。 生成的DLL现在到P​​ython可见。 下面是一个示例的Python会话:

>>> import hello_ext
>>> print hello_ext.greet()
hello, world


Answer 3:

你不能从ctypes的调用它,你至少需要翘曲C内的功能,所以你可以用Python调用它。

我不知道你的功能,但例如细节,如果你有这样的这个C ++代码:

#include <iostream>

class Foo {
  int bar;
public:
  Foo(int bar) : bar(bar) {}

  int getBar() const {
    return bar;
  }

  void setBar(int bar) {
    this->bar = bar;
  }

  void doSomething() const {
    std::cout << bar << std::endl;
  }
};

你可以弯曲INT这种方式:

// previous code here +
#define CAST_FOO(x) (static_cast<Foo *>(x))

#ifndef FOO_DEBUG
extern "C" {
#endif

void* foo_new(int bar) {
  return static_cast<void*>(new Foo(bar));
}

int foo_get_bar(void *foo) {
  return CAST_FOO(foo)->getBar();
}

void foo_set_bar(void *foo, int bar) {
  CAST_FOO(foo)->setBar(bar);
}
void foo_do_something(void* foo) {
  CAST_FOO(foo)->doSomething();
}

void foo_destroy(void* foo) {
  delete CAST_FOO(foo);
}

#ifndef FOO_DEBUG
};
#endif

#ifdef FOO_DEBUG
int main(int argc, char **argv) {
  void* foo = foo_new(10);

  foo_do_something(foo);
  foo_set_bar(foo, 20);
  foo_do_something(foo);

  foo_destroy(foo);

  return 0;
}
#endif

现在应该从ctypes的调用,并从C也。

$ g++ -Wall foo.cpp -DFOO_DEBUG
$ ./a.out
10
20
$ g++ -Wall foo.cpp -shared -o foo.so
$ python
>>> from ctypes import *
>>>
>>> so = cdll.LoadLibrary('foo.so')
>>> foo = so.foo_new(10)
>>>
>>> so.foo_do_something(foo)
10
>>> so.foo_set_bar(foo, 20)
>>> so.foo_do_something(foo)
20
>>> so.foo_destroy(foo)
>>>


文章来源: Calling complicated C++ functions in Python (linux)
标签: c++ python linux