Я пишу библиотеку, которая будет динамически загружаться на C++.
Я хотел бы читать argc и argv (для отладки) из моего кода, однако у меня нет доступа к основной функции. Есть ли способ получить командную строку (было бы неплохо как для Windows, так и для Linux).
Спасибо, Дэн





В Win32 API есть функция GetCommandLine (). На других платформах вам нужно будет где-нибудь сохранить argc / argv (внешняя переменная?).
В Linux псевдо-файл / proc / self / cmdline содержит командную строку для процесса. Каждый аргумент заканчивается нулевым байтом, а за последним аргументом следует дополнительный нулевой байт.
В этой ветке показано, как это сделать в Linux.
http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.system/2005-07/0147.html
Мне удалось найти поток в архиве: web.archive.org/web/20170424082824/http://linux.derkeiler.co м /… Похоже, это тот же ответ, что и @Darron, который должен прочитать / proc / self / cmdline
Могу я предположить, что это звучит как странная ситуация. Вы пишете плагин или что-то в этом роде? Возможно, вам не следует обращаться к argv / argc?
Я согласен. Если библиотеке нужен доступ к argv и argc, то, вероятно, библиотеке следует изменить дизайн.
GTK + требует (или принимает, не уверен) argc и argv для анализа, скажем, параметра --display. Это может быть полезно и в этом случае; подумайте "--debug".
argv и argc передаются в GTK +, что вполне разумно. То, что я имел в виду - и то, о чем просит DanJ - было способом для библиотеки получить доступ к argv и argc.
В Windows вы можете использовать GetCommandLine () для получения указателя на командную строку, а затем использовать CommandLineToArgvW () для преобразования этого указателя в формат argv []. Однако доступна только расширенная версия (Unicode).
Используйте getpid () и команду ps.
int pid;
int fd;
char cmd [80];
pid = getpid ();
sprintf (cmd, "ps% d", pid);
fd = popen (cmd, «г»);
.... строки должны быть похожи на
.... 1358 ./a.out abc def
В Windows вы можете получить доступ к argc / argv через __argc и __argv. __wargv, если вам нужна версия для широких символов.
Это действительно ужасная идея! Любой символ, имя которого начинается с двух знаков подчеркивания, зарезервирован для внутреннего использования реализацией компилятора. Вы должны никогда ссылаться на них в пользовательском коде. Это классический пример неопределенного поведения, причиненного самому себе - возможен любой (потенциально нежелательный) результат.
В 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 ().
Задумывались ли вы об использовании переменных среды вместо командной строки? Может быть проще для пользователя в зависимости от того, в каких приложениях будет использоваться библиотека, и вы можете использовать стандартную функцию getenv ().
Я думаю, что в любом случае, если ваша библиотека будет использовать argc и argv, программа должна их передать.
Это должно работать под 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 ().
Мертвая ссылка. Это одна из причин, по которой ответы, содержащие только ссылки, не приветствуются при переполнении стека. Мне удалось найти ветку в архиве: