将列表从Python传递到C++

8 投票
4 回答
4296 浏览
提问于 2025-04-18 13:52

我有一个Python程序,它会找到.txt文件的目录,然后把这些目录作为一个列表(我觉得是这样)传给我的C++程序。现在我遇到的问题是,我不太确定怎么把这个列表正确地传给C++。

subprocess.call(["path for C++ executable"] + file_list)

这里的file_list就是存放txt文件目录的[]

我的C++代码接受的参数是:

 int main (int argc, string argv[])

这样做对吗?还是说我应该用一个向量(vector)?当我把这个作为参数使用,并尝试打印出列表时,我得到的是可执行文件的目录、列表,然后是一些笑脸、符号,最后程序崩溃了。

有什么建议吗?我主要想弄清楚的是如何正确使用subprocess.call的语法。任何帮助都非常感谢!谢谢!

4 个回答

1

你把一个列表传给了 subprocess.call。这个 subprocess.call 会把这个列表转换成系统需要的格式(这个格式可能会有所不同,但肯定不是 Python 列表)。然后,系统会把这些内容复制到新进程中,并设置好传给 main 函数的标准参数,这些参数是 int, char**。在你的 C++ 程序中,你必须把 main 定义为 int main( int argc, char** argv );其他的写法都不行。(至少... 有些系统可能支持 int main( std::string const& ) 这样的扩展,但我从来没听说过有这样的系统。)

3

"通过Python将列表传递给C++"

另一种方法是使用Boost.Python,这可能不是直接回答你的问题,但提到另一种解决方案还是很有价值的。

#include <boost/python.hpp>
#include <vector>
#include <string>

void get_dir_list( boost::python::list dir_list )
{

    for (int i = 0; i < len(dir_list); ++i)
    {

        std::string x = boost::python::extract<std::string>(dir_list[i]);
        // perform stuffs
        std::cout << "This is " << x << std::endl ;
    }
}

BOOST_PYTHON_MODULE(get_dir_list)
{
    def("get_dir_list", get_dir_list);
}

编译命令: g++ main.cpp -shared -fPIC -o get_dir_list.so -I/usr/include/python2.7 -lboost_python


使用方法:

import get_dir_list
import os
get_dir_list.get_dir_list(os.listdir('.'))

在线演示在这里

6

还有一个选择是使用 cython,这不是直接的答案。下面是一个简单的完整示例:

假设你有以下文件:

cython_file.cpp
python_file.py
setup.py
sum_my_vector.cpp
sum_my_vector.h

setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension(
    name="cython_file", 
    sources=["cython_file.pyx", "sum_my_vector.cpp"],
    extra_compile_args=["-std=c++11"], 
    language="c++",
    )]

setup(
    name = 'cython_file',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules,
    )

cython_file.pyx

from libcpp.vector cimport vector

cdef extern from "sum_my_vector.h":
    int sum_my_vector(vector[int] my_vector)

def sum_my_vector_cpp(my_list):
    cdef vector[int] my_vector = my_list
    return sum_my_vector(my_vector)

sum_my_vector.cpp

#include <iostream>
#include <vector>
#include "sum_my_vector.h"

using namespace::std;

int sum_my_vector(vector<int> my_vector)
{
  int my_sum = 0;
  for (auto iv = my_vector.begin(); iv != my_vector.end(); iv++)       
      my_sum += *iv;

  return my_sum;
}

sum_my_vector.h

#ifndef SUM_MY_VECTOR
#define SUM_MY_VECTOR

using namespace::std;

int sum_my_vector(vector<int> my_vector);

#endif

python_file.py

from cython_file import sum_my_vector_cpp

print sum_my_vector_cpp([1,2,3,5])

现在运行

python setup.py build_ext --inplace

然后你就可以运行这个 Python 文件了。

python python_file.py
11
2

我来分享一个替代方案,因为它也适用于其他需要传递的长字符串列表。

在你的 Python 脚本中,创建一个文本文件(我称它为“masterFile”),然后把文件路径写入这个 masterFile。你可以把每个文件路径放在单独的一行。接着,把这个 masterFile 的文件路径传给你的 C++ 程序。这样你就不用担心命令行参数的长度问题了。让你的 C++ 程序打开并读取这个文件进行处理。

在你的 Python 脚本中,可以使用类似 os.remove() 的方法,在 C++ 程序完成后删除 masterFile。

另外,你在评论中提到需要根据不同的文件路径执行不同的任务:一个建议是在 masterFile 的每一行开头加一个字符,以指示对特定文件需要做什么。举个例子:

a Random/path/aFile.txt # a could mean do task 1
b Random2/path2/differentFile.c # b could mean do task 2

撰写回答