C++ 与 Python 函数通信

Posted

技术标签:

【中文标题】C++ 与 Python 函数通信【英文标题】:C++ to communicate to Python function 【发布时间】:2016-09-20 07:42:36 【问题描述】:

我是 C++ 新手,

我创建了包含类和函数的 DLL,每个函数的所有返回类型都是 PyObject(Python 对象),所以现在我想编写使用 LoadLibrary 函数动态加载 DLL 的 C++ 应用程序。

能够通过将项目添加到相同的解决方案并添加对 DLL 的引用来执行。

我可以加载DLL,但是当我调用它返回PyObject数据类型的函数时,如何在C++中存储PyObject的返回类型?

【问题讨论】:

你可以看看SWIG,这可以是一个很好的起点swig.org/Doc1.3/Python.html 【参考方案1】:

您应该查看Concrete Objects Layer 上的 Python 文档。基本上,您必须使用 Py*T*_As*T*(PyObject* obj) 形式的函数将 PyObject 转换为 C++ 类型,其中 T 是您要检索的具体类型。

API 假设您知道应该调用哪个函数。但是,正如doc 中所述,您可以在使用前检查类型:

...如果您从 Python 程序接收到一个对象,但您不确定它的类型是否正确,则必须先执行类型检查;例如,要检查对象是否为字典,请使用 PyDict_Check()

以下是将PyObject 转换为long 的示例:

PyObject* some_py_object = /* ... */;

long as_long(
    PyLong_AsLong(some_py_object)
);

Py_DECREF(some_py_object);

这是另一个更复杂的示例,将 Python list 转换为 std::vector

PyObject* some_py_list = /* ... */;

// assuming the list contains long

std::vector<long> as_vector(PyList_Size(some_py_list));

for(size_t i = 0; i < as_vector.size(); ++i)

    PyObject* item = PyList_GetItem(some_py_list, i);

    as_vector[i] = PyLong_AsLong(item);

    Py_DECREF(item);


Py_DECREF(some_py_list);

最后一个更复杂的示例,将 Python dict 解析为 std::map

PyObject* some_py_dict = /* ... */;

// assuming the dict uses long as keys, and contains string as values

std::map<long, std::string> as_map;

// first get the keys
PyObject* keys = PyDict_Keys(some_py_dict);

size_t key_count = PyList_Size(keys);

// loop on the keys and get the values
for(size_t i = 0; i < key_count; ++i)

    PyObject* key = PyList_GetItem(keys, i);
    PyObject* item = PyDict_GetItem(some_py_dict, key);

    // add to the map
    as_map.emplace(PyLong_AsLong(key), PyString_AsString(item));

    Py_DECREF(key);
    Py_DECREF(item);


Py_DECREF(keys);
Py_DECREF(some_py_dict);

【讨论】:

如何解析dict类型? 如果值包含字符串、字典和列表的组合,那么呢? 您可以使用PyString_Check()PyList_Check()PyDict_Check()检查PyObject的包装类型。然后,您必须根据检查结果使用正确的转换。您还必须对每个键/值组合使用 std::map,或者使用类型擦除,例如 std::variantstd::any(仅在 C++17 中可用)。 谢谢 :) 很有帮助 嗨,这很有帮助,但是如果我想在控制台上以 json 树格式显示 json 字符串或字典?

以上是关于C++ 与 Python 函数通信的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 函数与 Python 函数返回的值不一致,用于偏斜正态分布

在硬件上 C++ 和 Python 之间进行通信的最佳方式是啥? [关闭]

将 C++ 与 Python 连接

让 Java 与 Python、C、C++ 和 Ruby 对话

python实现一个客户端与服务端的通信

Python socket通信~简单实例