Nano Hash - криптовалюты, майнинг, программирование

несколько исходных файлов с основными функциями

В целях обучения я хочу иметь проект с несколькими исходными файлами, каждый из которых имеет свою собственную функцию main. Как можно этого добиться? Что я пытаюсь сделать, так это поместить все мои файлы C в один и тот же проект и выборочно скомпилировать те, над которыми я сейчас работаю. Или, что еще лучше, укажите имя файла в качестве аргумента программы, чтобы она могла его выполнить:

Например, в моем main.c я хотел бы иметь (где функции sample*_main находятся в разных файлах):

int main(int argc, char ** argv) {
    if (argc > 0)  {
        if (strstr(argv[0], "sample1")) return sample1_main(argc, argv);
        else if (strstr(argv[0], "sample2")) return sample2_main(argc, argv);
// etc...
    }
printf("Not sure what I should run.\n");
return -1;
}

Затем выполните программу следующим образом: main.exe sample1

У меня возникла проблема с ошибкой «множественное определение» при компиляции проекта такого типа, когда некоторые функции имеют общие имена в файлах sample*.c.


  • Я думаю, вы можете добиться этого, используя make 05.07.2013
  • Вы можете использовать определения макросов для основных функций в других файлах. при компиляции как библиотека определите ее как sample1_main иначе как main 05.07.2013
  • @VoidPointer, можете ли вы предоставить простой код, пожалуйста? 10.07.2013
  • @DimonBuzermann проверь мой ответ 10.07.2013
  • @DimonBuzermann надеюсь, ты получил то, что тебе нужно 10.07.2013

Ответы:


1

Кажется, ты на правильном пути.

Чтобы достичь своей цели, вы можете пойти следующим путем:

  1. переименуйте несколько main(), как в вашем примере кода, в sample1_main(), sample2_main()... (кстати, это позволяет избежать ошибки multiple definition of)
  2. оставьте main() из вашего поста как есть
  3. измените ваш make-файл таким образом, чтобы в зависимости от того, какой образец вы хотите запустить, созданный исполняемый файл назывался sample1, sample2, ... (для gcc параметр -o указывает имя исполняемого файла)
  4. вызывать исполняемый файл по его имени, то есть sample1 или sample2 или .... Нет необходимости передавать айн параметры.

Вот и все! :-)

Причина такого поведения в том, что argv[0] — это имя самого исполняемого файла.

05.07.2013

2

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

Таким образом, вы должны определить main.c, sample1.c, sample2.c и т. д., и в main.c у вас будет что-то вроде этого:

int main(int argc, char **argv) {
  char *methodToExecute;

  if (argc < 2) {
    printf("usage: main.exe <sample_name>\n");
    exit(-1);
  }

  methodToExecute = argv[1]; /* argv[0] is 'main.exe' */

  if (strcmp(methodToExecute, "sample1") == 0) {
    return sample1();
  }
  else if (strcmp(methodToExecute, "sample2") == 0) {
    return sample2();
  }

  /* etc. */
  else {
    printf("method not found: %s\n", methodToExecute);
    exit(-1);
  }
}
05.07.2013
  • Спасибо за предложение Питер. Я думаю, это именно то, что я делаю. Но, как я указал, если sample1.c и sample2.c содержат одни и те же идентификаторы (как в моем случае), я получаю множественное определение ошибки во время компиляции. 10.07.2013
  • Если у вас есть один или несколько символов (идентификаторов), на которые необходимо ссылаться в разных файлах, вам необходимо объявите их с модификатором extern в заголовочном файле и включите этот файл во все файлы, которые должны ссылаться на этот символ. Затем вы определяете переменную только в одном месте, и на это общее определение ссылается любой код, которому требуется доступ к символу. 10.07.2013

  • 3

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

    sm1.c:

    #include <stdio.h>
    
    #ifndef S1_MAIN
     #define S1_MAIN main
    #endif
    
    int S1_MAIN( int argc, char ** argv)
    {
    
        printf( "This is (sample1_main)\n" );
        return 0;
    }
    

    sm2.c:

    #include <stdio.h>
    
    #ifndef S2_MAIN
     #define S2_MAIN main
    #endif
    
    int S2_MAIN( int argc, char ** argv)
    {
    
        printf( "This is (sample2_main)\n" );
        return 0;
    }
    

    main.c:

    #include <stdio.h>
    #include <string.h>
    
    int sample1_main(int , char ** );
    int sample2_main(int , char ** );
    
    int main(int argc, char ** argv)
    {
        if (argc > 1)
        {
                if (strstr(argv[1], "sample1")) return sample1_main(argc, argv);
                else if (strstr(argv[1], "sample2")) return sample2_main(argc, argv);
        }
        printf("Not sure what I should run.\n");
        return 0;
    }
    

    Компиляция: (как отдельный двоичный файл)

    gcc -Wall -DS1_MAIN="sample1_main" -DS2_MAIN="sample2_main" main.c sm1.c sm2.c -o main
    
    ./main
    Not sure what I should run.
    ./main sample1
    This is (sample1_main)
    ./main sample2
    This is (sample2_main)
    

    Компиляция: (как отдельные двоичные файлы)

    gcc -Wall sm2.c -o sm2
    gcc -Wall sm1.c -o sm1
    ./sm1
    This is (sample1_main)
    ./sm2
    This is (sample2_main)
    

    Примечание. Я исправил основной файл для проверки аргументов командной строки.

    10.07.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..