在 C++ 中创建对象并将指针传递给 python
Posted
技术标签:
【中文标题】在 C++ 中创建对象并将指针传递给 python【英文标题】:Create object in C++ and pass pointer out to python 【发布时间】:2019-02-08 14:06:28 【问题描述】:我正在尝试使用 ctypes 与 Python 共享 C++ 对象,方法是在 C++ 中创建对象,并通过 C 包装器将指针传递给 Python。我希望稍后能够使用 Python 类中的其他函数对这个对象进行操作,do_something
在下面的代码中。
我尝试了以下代码,但出现了段错误。我是 C 与 C++ 和 C 与 Python 接口的新手,所以我不确定在传递指针时我是否在做一些根本性错误,或者内存是否被 Python 垃圾收集清除/移动,之后我创建对象?
This question 讨论了类似的 boost 问题,但答案对 ctypes 不是很有用。
object.h
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);
object.cpp
#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();
object.py
>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
任何帮助将不胜感激!
【问题讨论】:
你用什么命令将object.cpp编译成lib_object.so? 你有没有换过pointer
?否则 pointer->do_something()
取消引用空指针。另外,为什么是S->do_something()
而不是Ob->do_something
?
抱歉S->do_something()
打错了,我已经修正了
指针确实发生了变化:一个对象是从一个字符缓冲区重建的,然后pointer
指向该对象
argtypes 应该是一个列表(或 tuple):lib.object_pointer.argtypes = [c_void_p]
.
【参考方案1】:
注意事项:
没有编译问题中的文件(.cpp、.py)。它们包含语法错误和语义错误 我不知道 pointer 角色的用途是什么(它会产生 syntax 错误)。我只能假设尝试了 singleton 实现 考虑到上述情况,我没有在现有文件中指出错误(其中有很多错误),而是创建了一个全新的基本示例 虽然 ctypes 不是唯一需要改进的地方,但我也指出:[Python 2]: ctypes - A foreign function library for Pythonobject.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/***/q054594122]> ls object.cpp object.h object.py [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/***/q054594122]> gcc -shared -fPIC -o lib_object.so object.cpp -lstdc++ [cfati@cfati-5510-0:/cygdrive/e/Work/Dev/***/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
【讨论】:
谢谢,这很有帮助。将来我会尝试提供一个合适的独立示例,而不是从我的代码中提取随机位... 不客气! [SO]: How to create a Minimal, Complete, and Verifiable example (mcve).以上是关于在 C++ 中创建对象并将指针传递给 python的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C++ 中创建 Lua 表,并将其传递给 Lua 函数?
使用 SWIG 将 C++ 对象指针传递给 Python,而不是再次返回 C++
在 QML 中创建自定义 C++ 对象并将其存储在 C++ 模型中