我想从 C++ 脚本中获取一个 python 列表,例如 [1,2,3,4]
。我编写了 C++ 脚本,它返回一个 vector 。
没有SWIG/SIP/Cython/等如何连接两端?
将 C++ 编译为 .exe 或 elf 文件,然后从命令行调用,让 .exe 创建一个包含 vector 的 .txt 并用 python 读取它会更容易吗?
我的意思是,我只需要一个非常小的 C++ 函数来对大量数据进行繁重的计算。做到这一点最不痛苦和最短的方法是什么?
编辑: 举个例子。 Python 将文件名字符串提供给 C++(“foo.txt”),然后 C++ 将读取文件的上下文(200,000 行乘以 300 列),计算缺失的数量,然后将每行缺失的数量返回给 Python。这会产生一个包含 200,000 个数字的列表。 他们之间如何进行这种交流?
只是为了完整起见,这就是我仍然想知道如何去做的事情:
- 将 python 文件名字符串传递给 C++
- 在 C++ 中接收 python 字符串
- 完成在 C++ 中创建 vector
- 将 vector 返回给 Python
- 在 Python 中接收 vector
最佳答案
现在这可能没有实际意义,我在 your other question 上发布了类似的内容,但我已经为 Python 3.3 和 C++ 而不是 Python 2.7 和 C 改编了这个版本。
如果你想取回一个 Python 列表对象,并且由于你正在构建一个可能很长的列表(200,000 个项目),用 C++ 代码构建 Python 列表可能比构建一个 std::vector
,然后稍后将其转换为 Python 列表。
根据你另一个问题中的代码,我建议使用类似这样的东西......
// foo.cpp
#include <python3.3/Python.h>
#include <fstream>
#include <string>
using namespace std;
extern "C"
{
PyObject* foo(const char* FILE_NAME)
{
string line;
ifstream myfile(FILE_NAME);
PyObject* result = PyList_New(0);
while (getline(myfile, line))
{
PyList_Append(result, PyLong_FromLong(1));
}
return result;
}
}
...编译...
$ g++ -fPIC -shared -o foo.so foo.cpp -lpython3.3m
...以及使用示例...
>>> from ctypes import *
>>> foo = CDLL('./foo.so')
>>> foo.foo.restype = py_object
>>> foo.foo(b'foo.cpp')
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
...尽管如果您需要将现有的 std::vector
转换为 Python 列表,您可以通过将 vector 的长度传递给 Python 列表来预分配 Python 列表所需的内存PyList_New()
, 然后使用 PyList_SetItem()
而不是 PyList_Append()
.
我能想到的唯一其他方法是...
要在 Python 中预先分配一 block RAM,并让 C++ 函数填充值,就像 qarma 的答案一样,但您必须事先知道要分配多少 RAM。您可以只选择一个任意值,但考虑到文件中的行数事先未知,这个数字可能太大或太小。
要在 C++ 中堆分配
std::vector
,并返回指向第一个元素的指针和元素的数量,但您必须编写第二个函数完成后释放 RAM。
无论哪种方式,您仍有将“返回的”数组转换为 Python 列表的开销,因此您不妨自己动手。
关于C++ vector 到 Python 3.3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16693178/