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

查看:21
本文介绍了命令行参数的第二个参数采用 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 最小和 g++ 7.4.0 和 Windows 10 Visual Studio 2019 编译器.但是,它不能使用 clang 进行编译.正如其他人指出的那样,这不是解决方案,而且是一种非常糟糕的做法.根据编译器、操作系统和内存的当前状态,它可能会导致未定义的行为.这不应在任何实际代码中使用.任何 C/C++ 代码中的 main 函数必须采用 main()main(int argc, char** argv)main(intargc, 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});
}

<小时>

如果您需要调用封闭源代码的类似 main 的函数(您无法更改),请创建一个可以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天全站免登陆