我在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:
我已经给了一些功能。所以(与上面的参数类型,但函数的名称未知),函数名和参数是由用户输入。
我认为,你需要声明的助手胶水功能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蟒蛇插件 。 但是,这需要时间。
多做一些工作,但也许值得从长远来看是使用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现在到Python可见。 下面是一个示例的Python会话:
>>> import hello_ext
>>> print hello_ext.greet()
hello, world
你不能从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)
>>>