Могу ли я повторно скомпилировать файл с новым кодом?

#c #compilation #recompile

#c #Сборник #перекомпилировать

Вопрос:

У меня вопрос. Мне было интересно, не могли бы вы повторно скомпилировать код с другим фрагментом кода. Например (теоретически):

main.c:

 #include <stdio.h>

void showme();

int main()
{
   showme();
}

void showme()
{
   fprintf(stderr, "errtest, show me");
}
  

Скомпилируйте этот файл в main. (Итак, основной скомпилирован)
После этого я хочу добавить фрагмент кода.

addthis.c:

 void test()
{
   test();
}
  

Теперь я хочу использовать (скомпилированный) main и повторно скомпилировать его с помощью addthis.c.
При его запуске (./mainWithAddthis) должна отображаться печать 2 раза.

Надеюсь, я ясно объяснил это. У кого-нибудь есть идея?

Комментарии:

1. Вы можете скомпилировать файл без необходимости определять все вызываемые функции. Вам нужно определить функции только во время компоновки. Для создания исполняемого файла вам действительно нужно определить все функции. Ваш вопрос довольно странный. В чем ваша настоящая проблема?

2. Это домашнее задание? Если да, пожалуйста, добавьте homework тег к вашему вопросу.

3. @Tim В вашем воображении, что, по вашему мнению, произойдет, когда первый исполняемый файл вызовет несуществующую функцию? Кроме того, что происходит с бесконечной рекурсией в test() , и почему вы беспокоитесь о test() , поскольку ничто не вызывает ее (кроме нее самой)!

4. Вопрос не имеет смысла; test никогда не вызывается…

5. @Tim: Раздельная компиляция вряд ли является «границами C», это норма. Да, вы можете скомпилировать и связать модули spearate, но ваш пример кода имеет мало смысла в этом контексте.

Ответ №1:

Вам нужно прямое объявление для вашего, void test() как у вас есть для void showme() . Скомпилируйте каждый .c файл с -c опцией (только для компиляции):

  • gcc -c addthis.c -o addthis.o
  • gcc -c main.c -o main.o

Затем свяжите два объектных файла с:

  • gcc main.o addthis.o -o main

Тогда наслаждайтесь ./main 🙂

Комментарии:

1. Это не то, что было указано в вопросе. Он хочет использовать скомпилированный двоичный файл main с объектным файлом addthis.o для создания нового двоичного файла. Я не думаю, что это можно сделать!

2. Я согласен с Карлом, это не то, о чем просил OP, но опять же, вопрос очень неясен.

3. Вы предположили, что он тоже хотел использовать gcc, который он не указал. Но это хорошая информация, поскольку она дает конкретный пример и показывает, что сборка и компоновка — это двухэтапный процесс.

4. @Merlyn: Он сказал, ./mainWithAddthis поэтому я сказал gcc 🙂

5. После понимания ответов этот ответ является объективным, ясным и простым. Итак, поехали.

Ответ №2:

Ваш первый код не будет компилироваться, поскольку в нем нет определения test(); .

Как я понимаю, вы хотите взять скомпилированный main и добавить его с кодом, сгенерированным на addthis.o, чтобы создать второе приложение с именем mainWithAddthis . Это невозможно!

Вы либо запутались, либо пытаетесь проделать какой-то жесткий трюк.

Комментарии:

1. Если вы можете предоставить допустимый пример (компилируемый код) Я буду рад ответить на ваш вопрос.

2. Традиционно, если вы хотите добавить или заменить функцию в своем приложении, вы должны перекомпилировать исходные тексты. Вы не можете использовать существующий двоичный файл новый код для создания нового из этого. Но, если у вас есть доступ к обоим источникам, вы можете сделать: g main.o addthis.o -o main

3. «Ваш первый код не будет компилироваться, поскольку в нем нет определения test();» — это не имеет смысла; единственный вызов test() находится в addthis.c, внутри определения test() — который компилируется просто отлично.

4. @Jim Код был изменен с момента этого утверждения. В вопросе не отображается окно РЕДАКТИРОВАНИЯ, потому что пользователь сделал это в течение первых 2 минут (или что-то в этом роде) и ничего не написал в поле Редактировать сводку .

5. @karlphillip Господи, неужели? Еще одна идиотская «функция» SO, основанная на времени …. но в вашем комментарии выше говорится, что ваш ответ «обновлен» — он должен относиться к текущему вопросу, а не к чему-то навсегда скрытому.

Ответ №3:

Создание исполняемого файла — это двухэтапный процесс.

  1. Для каждого указанного вами исходного файла (в вашем проекте / makefile) ваш компилятор создаст объектный файл
  2. Для каждого указанного вами объектного файла (в вашем проекте / makefile) ваш компоновщик свяжет их вместе и создаст ваш исполняемый файл

Одним из способов повторной компиляции было бы просто перестроить весь ваш проект. Вы получите более или менее тот же результат.

Но похоже, что вы хотите перекомпилировать только исходный файл, addthis.c а затем повторно связать старую версию main.o (объектный файл, скомпилированный для main.c ) с новой версией addthis.o . Как это сделать, полностью зависит от используемого вами компилятора и системы сборки.

Кроме того, это решение будет работать, только если у вас есть main.o , addthis.c и имеют точно такие же двоичные файлы компилятора / install и флаги компилятора, используемые для генерации main.o . Если все это есть на вашем компьютере, то, вероятно, у вас все в порядке.

Если у вас есть только файлы addthis.c и main.exe , то нет переносимого способа сделать то, что вы хотите.

Ответ №4:

Вы не сможете сделать то, о чем говорите, постфактум, не потратив некоторое время на работу с шестнадцатеричным редактором.

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

Ответ №5:

main.c

 void f();
int main()
{
  f();
  return 0;
}
  

addon1.c

 #include <stdio.h>
void f()
{
  printf("I am the ONE.n");
}
  

addon2.c

 #include <stdio.h>
void f()
{
  printf("I am the TWO.n");
}
  

Сборник

 gcc -c main.c -o main.o
gcc -c addon1.c -o addon1.o
gcc -c addon2.c -o addon2.o
gcc main.o addon1.o -o main1
gcc main.o addon2.o -o main2
  

У вас будут программы ./main1 и ./main2 , которые будут печатать ...ONE. и ...TWO. .