Как я могу изменить точку входа для исполняемого файла Mach-O для файла C ++?

Я пытаюсь написать программу на C ++ без main. Можно ли изменить точку входа исполняемого файла mach-o на пользовательскую функцию (кроме main())?

Если нет, то можно ли обернуть main назвать мою версию основного до фактического C main называется?

Редактировать:

Я хочу, чтобы моя пользовательская функция вызывала C main, Если бы я дал ему атрибут конструктора или добавил его в список ctor, то main будет вызван дважды. Я не хочу, чтобы это произошло.

P.S Я создаю исполняемые файлы в Mac OS X High Sierra с версией Clang 9.1.0

2

Решение

Вы можете использовать -e <symbol> опция ld, которую вы можете вызвать как -Wl,-e,_<symbol> из лязга Исторически, точка входа в программу будет _start от crt0.o, однако это не было делом в Дарвине со времен Mac OS X 10.8 и iOS 6.0, где LC_MAIN была введена команда загрузки (замена LC_UNIXTHREAD). «Старый» способ все еще может быть использован, но должен быть явно включен с -no_new_main флаг компоновщика (который имеет аналог -new_mainЕсли вам это когда-нибудь понадобится). Обязанность, некогда выполняемая crt0.o, была перенесена на динамический компоновщик, /usr/lib/dyld, который может обрабатывать как LC_MAIN а также LC_UNIXTHREAD по мере необходимости.

Так, учитывая программу на C с main:

// t.c
#include <stdio.h>

int main(int argc, const char **argv)
{
printf("test %i\n", argc);
return 0;
}

Вы можете легко создать файл C ++, например так:

// t.cpp

extern int main(int, const char**);

extern "C" int derp(int argc, const char **argv)
{
return main(0, (const char*[]){ (const char*)0 });
}

И скомпилируйте их с clang++ -o t t.cpp -xc t.c -Wl,-e,_derp,
Просто не забудьте либо объявить derp как extern "C"или укажите искаженный символ в командной строке.

Вы также можете проверить полученный исполняемый файл с помощью otool чтобы убедиться, что он использует LC_MAIN скорее, чем LC_UNIXTHREAD:

bash$ otool -l ./t | fgrep -B1 -A3 LC_MAIN
Load command 11
cmd LC_MAIN
cmdsize 24
entryoff 3808
stacksize 0
3

Другие решения

Вы можете передать -e <symbol name> вариант для компоновщика (ld) указать другую точку входа. Точка входа по умолчанию не main; его start который предоставляется crt1.o и который, в свою очередь, вызывает main,

2

Вы можете использовать _start()

Он устанавливает некоторые вещи, заполняет массив аргументов argv, считает, сколько аргументов есть, а затем вызывает main, После main возвращается, exit называется.

Вот несколько ссылок:

https://stackoverflow.com/a/29694977/2302572

http://learningpearls.blogspot.com/2011/02/start-function-inside-c.html

0
По вопросам рекламы [email protected]