Аргументы командной строки доступа без использования char ** argv в главном

StackOverflow https://stackoverflow.com/questions/2471553

  •  20-09-2019
  •  | 
  •  

Вопрос

Есть ли способ получить доступ к аргументам командной строки, не используя аргумент в Main? Мне нужно получить доступ к нему в другой функции, и я бы предпочел не передавать его.

Мне нужно решение, которое обязательно работает только на Mac OS и Linux с GCC.

Это было полезно?

Решение

Я не думаю, что вы должны сделать это, так как время выполнения C подготовит аргументы и передаст их в основной через int argc, char **argv, не пытайтесь манипулировать поведением, взламывая его, так как оно было бы в значительной степени невозможным или, возможно, неопределенным поведением !! Придерживайтесь правил, и у вас будет портативность ... нет другого способа сделать это, кроме как разорвать ...

Другие советы

Я не знаю, как это сделать на macOS, но я подозреваю, что трюк, который я опишу здесь, может быть перенесен на macOS с небольшим количеством перекрестного чтения.

На Linux вы можете использовать так называемый раздел «.init_array» бинарного эльфа, чтобы зарегистрировать функцию, которая вызывается во время программы инициализации (до вызова main (). Эта функция имеет ту же подпись, что и нормальная функция Main (), выполняет ее возвращает «void». Таким образом, вы можете использовать эту функцию, чтобы запомнить или обрабатывать argc, argv [] и evp [].

Вот какой -то код, который вы можете использовать:

static void my_cool_main(int argc, char* argv[], char* envp[])
{
    // your code goes here
}

__attribute__((section(".init_array"))) void (* p_my_cool_main)(int,char*[],char*[]) = &my_cool_main;

PS: Этот код также можно помещать в библиотеку, поэтому он должен соответствовать вашему случаю. Это даже работает, когда ваша Prgram работает с Valgrind - Valgrind не разжигает новый процесс, и это приводит к/proc/self/cmdline, показывающему исходную командную линию Valgrind.

PPS: Имейте в виду, что во время этого очень раннего выполнения программы многие подсистема еще не полностью инициализированы - я попробовал процедуры ввода/вывода LIBC, они, кажется, работают, но не полагаются на нее - даже переменные переноса еще не могут быть построены, так далее...

Вы можете скопировать их в глобальные переменные, если хотите.

В Linux вы можете открыть /proc/self/cmdline (при условии, что /proc присутствует) и Parse вручную (это требуется, только если вам нужен argc/argv до main() - Например, в глобальном конструкторе - как иное, лучше передавать их через глобальные VAR).

Здесь доступно больше решений: http://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/

Да, это грубо и невозможно, но если вы решаете практические проблемы, вам может быть все равно.

Вы можете. Большинство платформ предоставляют глобальные переменные __ARGC и __ARGV. Но опять же, я поддерживаю комментарий Zneak.

PS Используйте Boost :: Program_options для их анализа. Пожалуйста, не делайте этого иначе в C ++.

Есть ли какая -то причина, по которой передача указателя на уже потребляемое пространство так плохо? Вы не получите реальных сбережений от устранения аргумента в отношении рассматриваемой функции, и вы можете выбрать интересный показ фейерверков. Опыт вокруг стека вызовов Main () с творческим хакари обычно оказывается в неопределенном поведении или зависимости от конкретного поведения компилятора. Оба плохо для функциональности и переносимости соответственно.

Имейте в виду, что рассматриваемые аргументы указатели Для аргументов они будут потреблять пространство, независимо от того, что вы делаете. Удобство их индекса столь же дешево, как и размер (int), я не вижу причин не использовать его.

Похоже, вы оптимизируете довольно агрессивно и преждевременно, или вы застряли в том, чтобы добавлять функции в код, с которыми вы действительно не хотите связываться. В любом случае, делать что -то условно сэкономит как время, так и неприятности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top