【问题标题】:How can I access argc and argv in c++ from a library function如何从库函数中访问 c​​++ 中的 argc 和 argv
【发布时间】:2008-10-01 23:56:56
【问题描述】:

我正在编写一个在 C++ 中动态加载的库。

我想从我的代码中读取 argc 和 argv(出于调试原因),但是我无法访问 main 函数。有什么方法可以检索命令行(Windows 和 Linux 都可以)。

谢谢, 丹

【问题讨论】:

    标签: c++ visual-c++ gcc


    【解决方案1】:

    在 Linux 上,伪文件 /proc/self/cmdline 包含进程的命令行。每个参数都以 0 字节结束,最后一个参数后跟一个额外的 0 字节。

    【讨论】:

      【解决方案2】:

      在 Win32 API 中有 GetCommandLine() 函数。在其他平台上,您必须将 argc/argv 保存在某个地方(外部变量?)。

      【讨论】:

        【解决方案3】:

        在 Windows 上,您可以通过 __argc 和 __argv 访问 argc/argv。 __wargv 如果你想要宽字符版本。

        【讨论】:

        • 这真是一个糟糕的主意!名称以两个下划线开头的任何符号都保留供编译器实现内部使用。您应该永远在用户代码中引用这些内容。这是一个典型的自我造成的未定义行为的例子——任何(可能不受欢迎的)结果都是可能的。
        【解决方案4】:

        我可以建议这听起来像一个奇怪的情况。你是在写插件还是什么?也许您不应该访问 argv/argc?

        【讨论】:

        • 我同意。如果一个库需要访问 argv 和 argc,那么该库可能需要重新设计。
        • GTK+ 需要(或接受,不确定)argc&argv 来解析,比如 --display 参数。在这种情况下它也可能有用;想想“--debug”。
        • argv 和 argc 被传递给 GTK+,这是非常明智的。我指的是——以及 DanJ 所要求的——是图书馆访问 argv 和 argc 的一种方式。
        【解决方案5】:

        在 Windows 中,您可以使用 GetCommandLine() 获取指向命令行的指针,然后使用 CommandLineToArgvW() 将该指针转换为 argv[] 格式。不过,只有一个宽 (Unicode) 版本可用。

        【讨论】:

          【解决方案6】:

          在 Windows 上,我使用这种类型的东西来获取参数:

          
          #include <windows.h>
          #include <string>
          #include <vector>
          #include <cwchar>
          #include <cstdio>
          #include <clocale>
          using namespace std;
          
          vector<wstring> getArgs() {
              int argc;
              wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
              vector<wstring> args;
              if (argv) {
                  args.assign(argv, argv + argc);
                  LocalFree(argv);
              }
              return args;
          }
          
          int main() {
              const vector<wstring> argv = getArgs();
              setlocale(LC_CTYPE, ".OCP");
              for (vector<wstring>::const_iterator i = argv.begin(); i != argv.end(); ++i) {
                  wprintf(L"%s\n", i->c_str());
              }
          }
          

          编辑:像这样的 getArgs 函数对 mingw 也很有用,因为 mingw 不支持 wmain()。

          【讨论】:

            【解决方案7】:

            这应该在linux下工作:

            #include <stdio.h>
            #include <unistd.h>
            
            void findargs(int *argc, char ***argv) {
                size_t i;
                char **p = &__environ[-2];
                for (i = 1; i != *(size_t*)(p-1); i++) {
                    p--;
                }
                *argc = (int)i;
                *argv = p;
            }
            
            int main(int argc, char **argv) {
                printf("got argc=%d, argv=%p\n", argc, argv);
                findargs(&argc, &argv);
                printf("found argc=%d, argv=%p\n", argc, argv);
                return 0;
            }
            

            注意:如果 setenv() 已被调用,则会失败。

            【讨论】:

              【解决方案8】:

              使用 getpid() 和 ps 命令。

              int pid;

              int fd;

              char cmd[80];

              pid = getpid();

              sprintf(cmd, "ps %d", pid);

              fd = popen(cmd, "r");

              .... 行应该是这样的

              .... 1358 ./a.out abc def

              【讨论】:

                【解决方案9】:

                您是否考虑过使用环境变量而不是命令行?根据库将用于何种应用程序,用户可能会更容易,您可以使用标准的 getenv() 函数。

                我认为,无论如何,如果您的库要使用 argc 和 argv,那么程序应该是传递它们的程序。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-08-10
                  • 2011-12-18
                  • 2012-08-16
                  • 2011-12-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-10-12
                  相关资源
                  最近更新 更多