命令行参数的第二个参数,格式为char ** argv或char * argv []以外的格式 [英] second argument of the command line arguments in a format other than char** argv or char* argv[]

查看:42
本文介绍了命令行参数的第二个参数,格式为char ** argv或char * argv []以外的格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要在此处解决我的问题,我想知道是否/如何定义命令行的第二个变量参数的格式不是char** argvchar* argv[]. 原因是pybind11不允许其中的任何一个函数的输入.这是我尝试过的方法:

To solve my problem here, I want to know if/how I can define the second variable of the command line arguments in a format other than char** argv or char* argv[]. The reason is that pybind11 doesn't allow either of those in the inputs of a function. Here are the methods I have tried:

#include <stdio.h>

int main(int argc, int* argv_){
    for (int i = 0; i < argc; ++i){
        printf("%s\n", (char *)(argv_[i]));
    }
}

此方法背后的原理是,指针本质上是整数,并且通过将地址强制转换为char指针,人们应该能够获取字符串.感谢您的提前支持.

The rationale behind this method is that a pointer is intrinsically an integer and by casting the address to a char pointer, one should be able to get the strings. Thanks for your kind support in advance.

#include <stdio.h>
#include <string>

int main(int argc, std::string* argv_){
    for (int i = 0; i < argc; ++i){
        printf("%s\n", argv_[i].c_str());
    }
}

方法3:

#include <stdio.h>
#include <string>
#include <vector>

int main(int argc, std::vector<std::string> argv_){
    for (int i = 0; i < argc; ++i){
        const char* argv__ = argv_[i].c_str();
        printf("%s\n", argv_[i].c_str());
    }
}

问题:

不幸的是,以上所有方法导致了臭名昭著的segmentation fault.

如果您能帮助我知道问题出在哪里(即内存泄漏在哪里)以及如何解决它们,我将不胜感激.

I would appreciate it if you could help me know what is the problem (i.e., where is the memory leak) and how to solve them.

在评论中,我被告知,如果使用任何其他形式而不是main()main(int argc, char** argv)main(int argc, char* argv[]),它将不可避免地导致segmentation fault.但是,下面的代码有效:

In the comments I'm being told that if any other form rather than main(), main(int argc, char** argv), or main(int argc, char* argv[]) is used, it will unavoidably lead to segmentation fault. However, the code below works:

#include <stdio.h>

int main(int argc, long* argv_){
    for (int i = 0; i < argc; ++i){
        printf("%s\n", (char *)(argv_[i]));
    }
}

这适用于Ubuntu minimal和g++ 7.4.0以及Windows 10 Visual Studio 2019编译器.但是,它不能使用clang进行编译.正如其他人指出的那样,这不是解决方案,而是一种非常不好的做法.它可能导致不确定的行为,具体取决于编译器,操作系统和内存的当前状态.永远不要在任何实际代码中使用它.任何C/C ++代码中的主要功能都必须采用main()main(int argc, char** argv)main(int argc, char* argv[])的形式.

This works on an Ubuntu minimal and g++ 7.4.0, and Windows 10 Visual Studio 2019 compilers. However, it does not compile with clang. As others have pointed out this is not a solution and a very bad practice. It can cause undefined behavior depending on the compiler, operating system and the current state of the memory. This should not be used in any actual code ever. The main function in any C/C++ code must be of the forms main(), main(int argc, char** argv), or main(int argc, char* argv[]).

推荐答案

毕竟看起来好像不需要是main,所以您可以这样做:

It doesn't look like it needs to be main after all, so you could do like this:

#include <iostream>
#include <string>
#include <vector>

int cppmain(std::string program, std::vector<std::string> args) {
    std::cout << program << " got arguments:\n";
    for(auto& arg : args) {
        std::cout << " " << arg << "\n";
    }
    return 0;
}

int main(int argc, char* argv[]) {
    // create a string from the program name and a vector of strings from the arguments
    return cppmain(argv[0], {argv + 1, argv + argc});
}


如果您需要调用封闭的源类主函数(您无法更改),请创建一个包装器函数,您可以pybind对其进行调用,然后让该函数调用封闭的源函数.


In case you need to call a closed source main-like function (that you can not change), create a wrapper function that you can pybind to and let that function call the closed source function.

#include <cstddef>
#include <iostream>
#include <string>
#include <vector>

int closed_source_function(int argc, char* argv[]) {
    for(int i = 0; i < argc; ++i) {
        std::cout << argv[i] << '\n';
    }
    return 0;
}

int pybind_to_this(std::vector<std::string> args) {
    // create a char*[]
    std::vector<char*> argv(args.size() + 1);

    // make the pointers point to the C strings in the std::strings in the
    // std::vector
    for(size_t i = 0; i < args.size(); ++i) {
        argv[i] = args[i].data();
    }

    // add a terminating nullptr (main wants that, so perhaps the closed source
    // function wants it too)
    argv[args.size()] = nullptr;

    // call the closed source function
    return closed_source_function(static_cast<int>(args.size()), argv.data());
}

这篇关于命令行参数的第二个参数,格式为char ** argv或char * argv []以外的格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆