我有一个 C++ 程序,它公开了一个 Python 接口(interface)来执行用户的嵌入式 Python 脚本。

用户插入要运行的 Python 脚本的路径和命令行参数。
然后脚本通过

boost::python::exec_file(filename, main_globals, main_globals)

要将命令行参数传递给 Python 脚本,我们必须通过 Python C-API 函数设置它们
PySys_SetArgv(int args, char** argv)

在调用 exec_file() 之前。

但这需要对包含命令行参数的用户字符串进行标记以获取参数列表,然后通过 PySys_SetArgv 将它们传递回 Python 解释器。
这不仅仅是浪费时间,因为通过这种方式,主 C++ 程序必须在不知道背后逻辑的情况下承担对命令行字符串进行标记的责任,这仅在自定义用户的脚本中定义。

在元代码中,一个更好更干净的方法是这样的:
string command_line_args = '-v -p "filename" -t="anotherfile" --list="["a", "b"]" --myFunnyOpt'
exec_file( filename, command_line_args, ...)

我花了几个小时查看 Boost 和 Python C-API 文档,但没有发现任何有用的东西。
你知道是否有办法实现这一点,即传递一整串命令行
来自 C++ 的嵌入式 Python 脚本的参数?

更新:

正如史蒂夫在下面的评论中所建议的那样,我解决了在 https://stackoverflow.com/a/8965249/320369 之后标记输入字符串的问题。

就我而言,我使用了:
// defining the separators
std::string escape_char = "\\"; // the escape character
std::string sep_char = " "; // empty space as separator
std::string quote_char = ""; // empty string --> we don't want a quote char'
boost::escaped_list_separator<char> sep( escape_char, sep_char, quote_char );

因为我也希望能够解析包含字符串的元组,例如:
'--option-two=("A", "B")'

如果您使用:
escaped_list_separator<char> sep('\\', ' ', '"');

就像在原始帖子中一样,您没有正确标记带引号的字符串。

最佳答案

由于您不反对执行外部文件,因此您可以使用帮助程序让您的 shell 命令为您进行解析。您的助手程序可能是:

#include <stdio.h>
int main (int argc, char *argv[])
{
    for (int i = 1; i < argc; ++i) printf("%s\n", argv[i]);
    return 0;
}

然后你可以有代码将你的单个参数字符串发送到帮助程序(可能使用 popen )并读回解析的参数,每个参数在单独的行上。
unparsed_line.insert(0, "./parser_helper ");
FILE *helper = popen(unparsed_line.c_str(), "r");
std::vector<std::string> args;
std::vector<const char *> argv;
std::string arg;
while (fgetstring(arg, helper)) {
    args.push_back(arg);
    argv.push_back(args.rbegin()->c_str());
}
pclose(helper);
fgetstring 例程是我写的,就像 fgetsstd::getline 之间的交叉。它一次从 FILE * 中读取一行,填充一个 std:string 参数。
static bool
fgetstring (std::string &s, FILE *in)
{
    bool ok = false;
    std::string r;
    char buf[512];
    while (fgets(buf, sizeof(buf), in) != 0) {
        ++ok;
        r += buf;
        if (*r.rbegin() == '\n') {
            r.resize(r.size()-1);
            break;
        }
    }
    if (ok) s = r;
    return ok;
}

我似乎记得 SO 上的一个帖子有类似的例程,但我找不到它。如果我以后找到它,我会更新我的帖子。

关于c++ - 如何将命令行参数作为字符串传递给从 C++ 执行的嵌入式 Python 脚本?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10740627/

10-12 00:54
查看更多