我有一个C ++程序,它公开了一个Python接口来执行用户的嵌入式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 ++程序必须负责标记命令行字符串而不知道后面的逻辑,这只在自定义用户的脚本中定义。
更好更清洁的方法在metacode中会是这样的:
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('\\', ' ', '"');
与原始帖子一样,您没有正确标记引用的字符串。
答案 0 :(得分:1)
由于您不会执行外部文件,因此可以使用帮助程序使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
)并读回解析的参数,每个arg在一个单独的行上。
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
例程就像fgets
和std::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上有一个类似于此例程的帖子,但我找不到它。如果我以后再找到它,我会更新我的帖子。