【问题标题】:Create object in C++ and pass pointer out to python在 C++ 中创建对象并将指针传递给 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].

标签: python c++ ctypes


【解决方案1】:

注意事项

  • 没有编译问题中的文件(.cpp.py)。它们包含语法错误和语义错误
  • 我不知道 pointer 角色的用途是什么(它会产生 syntax 错误)。我只能假设尝试了 singleton 实现
  • 考虑到上述情况,我没有在现有文件中指出错误(其中有很多错误),而是创建了一个全新的基本示例
  • 虽然 ctypes 不是唯一需要改进的地方,但我也指出:[Python 2]: ctypes - A foreign function library for Python

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

【讨论】:

猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 2019-02-07
  • 2022-01-08
  • 1970-01-01
  • 2018-09-03
相关资源
最近更新 更多