如何使用 ctypes 将此 Python 对象移动到 C++ 中?

Posted

技术标签:

【中文标题】如何使用 ctypes 将此 Python 对象移动到 C++ 中?【英文标题】:How can I move this Python object into C++ using ctypes? 【发布时间】:2019-07-07 16:58:32 【问题描述】:

这是一个较大问题的一小部分,但我有一个 C++ 类,我正在 python 中初始化,当我尝试将对象从 python 传递回 C++ 时,没有任何初始化值进行转换。

原始类来自 C++,它是在 Python 中初始化的,当我尝试将初始化的对象移回 C++ 时出现问题。

Python 代码

from ctypes import c_int, c_double, CDLL, Structure


lib = CDLL('./libDftConfig.so')

class Atom(Structure):
  _fields_ = [('type_', c_int), ('x_', c_double), 
              ('y_', c_double), ('z_', c_double)]

  # Using C++ class 
  def __init__(self, t, x, y, z):
    self.obj = lib.Atom_init(t, x, y, z)


def wrap_function(lib, funcname, restype, argtypes):
  func = lib.__getattr__(funcname)
  func.restype = restype
  func.argtypes = argtypes
  return func

# wrap the C++ function
print_atom = wrap_function(lib, 'py_print_atom', None, [Atom]) 

# Initialize C++ class and pass it back to C++ here
print_atom(Atom(50,5,10,15)) 

C++ 代码

#include <iostream>

struct Atom 
public:
    Atom(int type, double x, double y, double z) : type_(type), x_(x), y_(y), z_(z)   
    int     type_;
    double  x_;
    double  y_;
    double  z_;
;

std::ostream& operator<<(std::ostream &strm, const Atom &atom) 
    return strm << atom.type_ << " " << atom.x_ << " " << atom.y_ << " " << atom.z_ << std::endl;


void print_atom(Atom atom)

  std::cout << atom << std::endl;


extern "C"

  Atom* Atom_init(int type, double x, double y, double z)
  
    return new Atom(type, x, y, z);
  
  void py_print_atom(Atom atom)print_atom(atom);

预期:50 5 10 15 实际:0 0 0 0

【问题讨论】:

【参考方案1】:

我不确定我会给你最好的答案,我不会检查它(这只是凭经验)。

首先我会写出 Atom Init 的返回类型,以防万一。

lib.Atom_init.restype = ctypes.c_void_p

然后我会在有外化的地方写 C++ 代码

void py_print_atom(Atom * atom)print_atom(*atom);

最后修改python代码。

print_atom = wrap_function(lib, 'py_print_atom', None, [ctypes.c_void_p]) 

这样我很确定它会起作用。这就是我将 C++ 函数外部化的方式。如果您不想手动操作,您也可以使用 Boost::Python(但我想您知道 :D)。

希望对你有所帮助。

【讨论】:

在进行建议的更改后出现以下错误:" print_atom(Atom(50,5,10,15)) ctypes.ArgumentError: argument 1: : wrong输入“但它给了我一个想法,我稍后会尝试。谢谢。

以上是关于如何使用 ctypes 将此 Python 对象移动到 C++ 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ctypes 的 c_long 转换为 Python 的 int?

Python 对象作为 ctypes 回调函数中的用户数据

将 multiprocessing.Value 对象传递给 ctype 函数?

Python - 将字符串对象转换为 ctypes (unsigned char *)

Python ctypes:如何将 ctypes 数组传递给 DLL?

如何使用 ctypes 在 python 中正确包装 C API?