Есть ли способ компилировать дополнительный код во время выполнения в C или C ++?
=================================================================================

Вот что я хочу сделать:

Run a program and initialize some data structures.
Then compile additional code that can access/modify the existing data structures.
Repeat step 2 as needed.

Я хочу быть в состоянии сделать это с обоими`C` а также`C++` с помощью`gcc` (и в конце концов`Java`) в Unix-подобных системах (особенно в Linux и Mac OS X). Идея состоит в том, чтобы в основном реализовать цикл read-eval-print для этих языков, который компилирует выражения и операторы по мере их ввода и использует их для изменения существующих структур данных (что постоянно делается на языках сценариев). Я пишу этот инструмент в`python`, который генерирует`C`/`C++` файлы, но это не должно быть актуальным.

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

Я бы предпочел не использовать какие-либо компиляторы, кроме`gcc` если нет абсолютно никакого способа сделать это в`gcc`.

Если у кого-то есть идеи или они знают, как это сделать, любая помощь будет принята с благодарностью.

 что вы можете сделать это, используя динамические библиотеки и загружая их во время выполнения (используя`dlopen` и друзья)

 Очевидно, вам придется компилировать новый код по мере продвижения, но если вы продолжите заменять`mynewcode.so` Думаю, это подойдет тебе.



 что LLVM сегодня используется в основном для его оптимизации и внутренних функций при компиляции, его ядром является низкоуровневая виртуальная машина.

LLVM может JIT-код, хотя типы возвращаемых данных могут быть довольно непрозрачными, поэтому, если вы готовы обернуть свой собственный код вокруг него и не слишком беспокоиться о предстоящих приведениях, это может вам помочь.

 Однако C и C ++ не очень дружелюбны для такого рода вещей.



Это можно сделать с помощью OpenC [OpenCL](https://www.khronos.org/opencl) это [широко поддерживается](https://www.khronos.org/conformance/adopters/conformant-products#opencl) стандарт, в основном используется для выгрузки вычислений на специализированное оборудование, такое как графические процессоры. Тем не менее, он также отлично работает на процессорах и фактически выполняет компиляцию кода, подобного C99, во время выполнения, как одну из его основных функций (именно так достигается аппаратная переносимость). Более новые версии (2.1+) также принимают большое подмножество C ++ 14.

 Базовый пример такой компиляции и выполнения во время выполнения может выглядеть примерно так:



  [Runtime Скомпилировано C ++](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus) (или посмотрите на [RCC ++ блог и видео](https://runtimecompiledcplusplus.blogspot.com/)) или один из его [Альтернативы](https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus/wiki/Alternatives).



 

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

 **Structs.h:**

 **Main.cpp:**

**выход**

 Ты тоже можешь создать **изменяемая программа**, который изменит себя (исходный код), перекомпилирует себя и затем заменит фактическое выполнение на**`execv`** и экономьте ресурсы с общей памятью.



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

 1) использовать system () или что-то еще для выполнения gcc или make или что-то еще для сборки кода

 2) либо связать его как простой двоичный файл, либо проанализировать любой формат (эльф?), Который выводит компоновщик на вашей платформе

 3) найдите себе исполняемые страницы, либо запустив mmap () исполняемый файл, либо сделайте анонимный mmap с установленным битом выполнения и скопируйте / распакуйте там свой код (не все платформы заботятся об этом бите, но давайте предположим, что вы есть тот, который делает)

 4) очистить любые кэши данных и инструкций (поскольку согласованность между ними обычно не гарантируется)

 5) вызывать его через указатель на функцию или как угодно

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