#attributes #d #main #weak #scriptedmain
#атрибуты #d #program-entry-point #слабый #scriptedmain
Вопрос:
Если вам действительно нужно, вы можете указать __attribute__((weak))
на C (см. scriptedmain ). Это позволяет программе работать как с API, так и с исполняемым файлом, позволяя коду, который импортирует API, перезаписывать основную функцию.
Есть ли у D способ сделать это? У Python есть if __name__=="__main__": main()
, но weak
синтаксис в C кажется намного ближе.
Ответ №1:
Да, с использованием директив версии, которые требуют специальных опций для rdmd и dmd.
scriptedmain.d:
#!/usr/bin/env rdmd -version=scriptedmain
module scriptedmain;
import std.stdio;
int meaningOfLife() {
return 42;
}
version (scriptedmain) {
void main(string[] args) {
writeln("Main: The meaning of life is ", meaningOfLife());
}
}
test.d:
#!/usr/bin/env rdmd -version=test
import scriptedmain;
import std.stdio;
version (test) {
void main(string[] args) {
writeln("Test: The meaning of life is ", meaningOfLife());
}
}
Пример:
$ ./scriptedmain.d
Main: The meaning of life is 42
$ ./test.d
Test: The meaning of life is 42
$ dmd scriptedmain.d -version=scriptedmain
$ ./scriptedmain
Main: The meaning of life is 42
$ dmd test.d scriptedmain.d -version=test
$ ./test
Test: The meaning of life is 42
Также опубликовано на RosettaCode.
Комментарии:
1. Технически вы не переопределяете main, а используете условную компиляцию. Это ближе к
#ifdef
, чем к__attribute__
.2. вы можете использовать
pragma(startaddress,foo)
операторы wrapped in version для получения того же результата без переноса основных функций в версии3. @ratchetfreak Круто! Пожалуйста, приведите полный пример его использования.
Ответ №2:
Я считаю __attribute__((weak))
, что это расширение GNU, которое выдает специальные инструкции компоновщика для слабой компоновки, поэтому оно очень специфично для набора инструментов. В DMD нет ничего для этого AFAIK, но другие общие компиляторы (GDC или LDC) могут поддерживать расширения своих бэкэндов.
Ответ №3:
IIRC существует способ заставить код компилироваться в библиотеку, а не в объектный файл. Из-за того, как компоновщик выполняет поиск объектов, вы можете использовать это для получения того же эффекта; просто поместите цель с main, которую вы хотите использовать первой в порядке ссылки.