我正在尝试使用ctypes与Python共享C ++对象,方法是在C ++中创建对象,然后通过C包装器将指针传递给Python。我希望以后可以使用以下代码中的Python类do_something
中的其他函数对该对象进行操作。
我尝试了以下代码,但遇到了段错误。我不熟悉C与C ++和C与Python的接口,因此我不确定在传递指针时是否在做根本上错误的事情,或者在我执行完之后是否被Python垃圾收集清除/移动了内存创建对象?
This question讨论了关于boost的类似问题,但是答案对于ctypes不是很有用。
class object {
public:
// constructor
object() {
pointer = nullptr;
}
// destructor
virtual ~object() {
delete pointer;
pointer = nullptr;
}
// get member functions of object_pointer
// from C++
double do_something();
protected:
// pointer to the object
object_pointer *pointer;
};
extern "C" {
object* object_new();
void object_delete(object *Ob);
double object_do_something(object *Ob);
}
#include "object.h"
double object::do_something() { return pointer->do_something(); }
extern "C" {
object *object_new() { return new object(); }
void object_delete(object *Ob) { delete Ob; }
double object_do_something(object *Ob) { return Ob->do_something(); }
}
from ctypes import *
lib = cdll.LoadLibrary('./lib_object.so')
lib.object_new.argtypes = ()
lib.object_new.restype = c_void_p
lib.special_delete.argtypes = c_void_p,
lib.special_delete.restype = None
lib.object_pointer.argtypes = c_void_p
lib.object_pointer.restype = c_void_p
class Object:
def __init__(self):
self.obj = lib.object_new()
print self.obj
def __del__(self):
lib.object_delete(self.obj)
def do_something(self):
lib.object_do_something(self.obj)
s = Object()
>> 94549743086144
s.do_something()
>> Segfault
任何帮助将不胜感激!
答案 0 :(得分:2)
注释:
object.h :
class Object {
public:
Object() {
m_double = 2.718282;
}
virtual ~Object() {}
double do_something();
private:
double m_double;
};
extern "C" {
Object* object_new();
void object_delete(Object *ob);
double object_do_something(Object *ob);
}
object.cpp :
#include <iostream>
#include "object.h"
using std::cout;
double Object::do_something() {
std::cout << "Doing something in C++\n";
return m_double;
}
extern "C" {
Object *object_new() { return new Object(); }
void object_delete(Object *pObj) { delete pObj; }
double object_do_something(Object *pObj) { return pObj->do_something(); }
}
object.py :
#!/usr/bin/env python2
import sys
import ctypes
lib = ctypes.cdll.LoadLibrary('./lib_object.so')
lib.object_new.argtypes = []
lib.object_new.restype = ctypes.c_void_p
lib.object_delete.argtypes = [ctypes.c_void_p]
lib.object_do_something.argtypes = [ctypes.c_void_p]
lib.object_do_something.restype = ctypes.c_double
class Object:
def __init__(self):
self.obj = lib.object_new()
print("`Object` instance (as a `void *`): 0x{:016X}".format(self.obj))
def __del__(self):
lib.object_delete(self.obj)
def do_something(self):
return lib.object_do_something(self.obj)
def main():
obj = Object()
ret = obj.do_something()
print(ret)
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
输出:
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054594122]> ls object.cpp object.h object.py [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054594122]> gcc -shared -fPIC -o lib_object.so object.cpp -lstdc++ [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q054594122]> python2 object.py Python 2.7.14 (default, Oct 31 2017, 21:12:13) [GCC 6.4.0] on cygwin `Object` instance (as a `void *`): 0x0000000600078870 Doing something in C++ 2.718282