我有一个用C ++编写的Windows应用程序。我有一个字符串向量,我需要传递给python脚本进行处理。我知道如何在C ++中使用简单类型嵌入python,但我正在研究如何创建一个等效于字符串向量的python对象。我正在寻找类似的东西:
for (size_t i = 0; i < myvector.size(); ++i)
{
PyUnicode_FromString.append(myvector[i]);
}
或者
for (size_t i = 0; i < myvector.size(); ++i)
{
pValue = PyUnicode_FromString(myvector[i]);
pyTuple_SetItem(myvector.size(), i, pValue);
}
矢量几乎不会变得非常大(我会说最多100项)。目前我只是保存一个文本文件,我有python脚本打开它并处理它显然不是很好,但它告诉我其他一切按计划工作。 Python脚本的处理每个项目产生4个值(3个字符串和1个整数(长整数))。我还需要返回主要的C ++程序,我不知道如何去做。 (编辑)在审查了可能的选项之后,我想到了一个列表列表(因为字典没有被排序,需要更多的解析操作)应该做的但我不知道如何在C ++中解码这个程序(现在再次使用文件写入/读取,所以我知道它的工作原理)。如果有人这样做了,你能不能提供小代码片段,以便我可以根据自己的需要进行调整。我还要提一下,我不能使用boost库(最好也不能使用SWIG) - 所以,基本上是在Python C-API中完成的。我见过的所有关于子过程或NumPy的例子我不相信(可能不正确)适用于我的案例。
答案 0 :(得分:1)
好吧,我设法找出了我想要的东西。下面是我试图做的一个完整工作的例子。答案是不完整的,因为有很多错误检查丢失,更重要的是缺少一些Py_DECREF。我会尝试抓住它们并在我弄清楚的时候进行更新,但如果有人能说这种东西可以提供帮助,那将非常感激。这是:
Python脚本:(testingoutput.py)此脚本接收字符串列表,对于每个字符串,它返回3个随机字符串(来自提供的列表)和一个随机整数。格式为:[[sssi],]
import random
import string
def get_list_send_list(*input_list):
outer_list = []
for key in input_list:
inner_list = []
# from here, your program should produce the data you want to retrieve and insert it in a list
# for this example, a list comprised of 3 random strings and 1 random number is returned
for i in range (0, 3):
some_words = random.choice(["red", "orange", "yellow", "green", "blue", "purple", "white", "black"])
inner_list.append(some_words)
inner_list.append(random.randint(1,10))
outer_list.append(inner_list)
return outer_list
这是cpp文件。与Python C API示例大致相同,但略微修改以容纳列表。我不需要这个以满足我的需求,但我在这里和那里进行了一些类型检查,以便任何可能需要那种东西的人受益。
#include <Python.h>
#include <iostream>
#include <vector>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
PyObject *pList, *pListItem, *pyString;
char* strarray[] = {"apple", "banana", "orange", "pear"};
std::vector<std::string> strvector(strarray, strarray + 4);
std::string pyFile = "testingoutput";
std::string pyFunc = "get_list_send_list";
Py_Initialize();
pName = PyUnicode_FromString(pyFile.c_str());
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL)
{
pFunc = PyObject_GetAttrString(pModule, pyFunc.c_str());
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(strvector.size());
for (size_t i = 0; i < strvector.size(); ++i)
{
pValue = PyUnicode_FromString(strvector[i].c_str());
if (!pValue)
{
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL)
{
int py_list_size = PyList_Size(pValue);
int sub_list_size = 0;
std::cout << "Retrieving content..."<< "\n";
for(Py_ssize_t i = 0; i < py_list_size; ++i)
{
pList = PyList_GetItem(pValue, i);
sub_list_size = PyList_Size(pList);
// verify if the subitem is also a list - if yes process it
if(PyList_Check(pList))
{
std::cout << "********** " << i << " **********\n";
for(Py_ssize_t j = 0; j < sub_list_size; ++j)
{
pListItem = PyList_GetItem(pList, j);
// verify if the item is a string or a number
if(PyUnicode_Check(pListItem))
{
// "Error ~" does nothing here but it should be defined to catch errors
pyString = PyUnicode_AsEncodedString(pListItem, "utf-8", "Error ~");
const char *tmpCstChar = PyBytes_AS_STRING(pyString);
std::cout << "Item " << j << ": " << tmpCstChar << "\n";
}
else if(PyLong_Check(pListItem))
{
int pyNumber = PyLong_AsLong(pListItem);
std::cout << "Item " << j << ": " << pyNumber << "\n";
}
}
}
else
{
std::cout << "This item is not a list\n";
}
}
Py_DECREF(pValue);
}
else
{
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else
{
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else
{
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
Py_Finalize();
return 0;
}
同样,缺少一些错误检查,更重要的是,缺少一些Py_DECREF。即该程序正在泄漏内存。如果你知道如何解决这个问题,我们将不胜感激。