Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
#1

Компиляция исходного кода в работающей программе - C++

07.07.2014, 16:21. Просмотров 1568. Ответов 47
Метки нет (Все метки)

Привет.

Подскажите, как можно скомпилировать код, и использовать полученный результат в запущенной программе, если этот самый код находится, в компоненте (memo, list итд - неважно) этой запущенной пргораммы.

Я нашел 1 вариант - это сохранение этого кода в файл и компиляция в отдельном процессе.
Это правильный вариант? и есть ли еще пути решения?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2014, 16:21
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Компиляция исходного кода в работающей программе (C++):

Загрузка исходного кода и компиляция *.exe - C++
Помогите разобраться как в Visual Studio 2010 загрузить исходный код для компиляции программы?

Компиляция исходного кода C++ ubuntu если нет компилятора g++ - C++
как запустить кода C++ в ubuntu если нет компилятора g++. код набран в текстовых файлах main.cpp func.cpp f.cpp func.h f.h в...

Исправить ошибку в программе, работающей с дробями - C++
#include <iostream> using namespace std; int main(){ int a,b,c,d,e,f; cout << "Введите первую дробь:/n"; cin >> a >> "/" >> b;...

Компиляция кода в приложении - C++
Можно каким-либо образом скомпилировать код в работающем приложении. Т.е. приложение работает, в него подается файл с исходным кодом, его...

Компиляция кода Freeglut - C++
Здравствуйте. Стоит Ubuntu 12.10, компилятор g++ , библиотеку freeglut поставил из репозитория, после чего инклуды появились нужном месте в...

Компиляция кода в командной строке - C++
на паре нам показывали как работать с прогой, написанной на ассемблере - cmd-> выбор директории -> создание объектного файла с помощью...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
07.07.2014, 18:18 #16
Цитата Сообщение от vlinx Посмотреть сообщение
но пока не получилось возвратить результат в программу.
Без специальных ухищрений и не получится (ну кроме целочисленного результата из main).

Если я правильно понял, то вариант 3) - это как раз модифицированный вариант 1). Компилятор вызывается, собирает код в dll, потом эта dll загружается в приложение и вызывается функция. Шаблон здесь конечно же не С++. Я думаю имелось в виду, что имена функций в dll и их сигнатура должны быть типовыми (т.е. строится по шаблону), иначе мы не будем знать что же нам вызывать в итоге.

Добавлено через 5 минут
А, и да. К четвертому варианту надо бы еще добавить и это. Там есть пример (main.cpp).
1
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
07.07.2014, 19:08 #17
Цитата Сообщение от vlinx Посмотреть сообщение
Если нет, то где почитать про процесс встраивания кода в шаблон dll?
Цитата Сообщение от DrOffset Посмотреть сообщение
Компилятор вызывается, собирает код в dll, потом эта dll загружается в приложение и вызывается функция. Шаблон здесь конечно же не С++. Я думаю имелось в виду, что имена функций в dll и их сигнатура должны быть типовыми (т.е. строится по шаблону), иначе мы не будем знать что же нам вызывать в итоге.
Коллега DrOffset совершенно верно пояснил эту идею вплоть до деталей.
2
AlexVRud
442 / 152 / 38
Регистрация: 04.07.2014
Сообщений: 431
07.07.2014, 19:55 #18
Подкину ещё идею. Можно посмотреть в сторону встраивания скриптовых языков в программу, например Lua. Делается это намного проще.
0
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 13:10  [ТС] #19
Цитата Сообщение от DrOffset Посмотреть сообщение
Если я правильно понял, то вариант 3) - это как раз модифицированный вариант 1). Компилятор вызывается, собирает код в dll, потом эта dll загружается в приложение и вызывается функция. Шаблон здесь конечно же не С++. Я думаю имелось в виду, что имена функций в dll и их сигнатура должны быть типовыми (т.е. строится по шаблону), иначе мы не будем знать что же нам вызывать в итоге.
Руками собрал и скомпилил dll при помощи mingw, а вот с помощью CreatProcess не создается файл example_dll.o

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
    //string path_compiler = "C:\\strawberry\\c\\bin\\g++.exe g++";
   // string cmd1 = "g++ -c -DBUILDING_EXAMPLE_DLL example_dll.cpp";
 
    STARTUPINFO siForNotepad = {sizeof(siForNotepad)};
    PROCESS_INFORMATION piForNotepad;
    TCHAR czCommandLine[] = "C:\\strawberry\\c\\bin\\g++ -c -DBUILDING_EXAMPLE_DLL D:\\example_dll.cpp";//Запоминаем имя приложения в параметре командной строки
 
    if(CreateProcess(NULL, czCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &siForNotepad, &piForNotepad))
    {
        cout << "Process " << czCommandLine << " successfully!\n";
        cout << "Descriptor process: " << piForNotepad.hProcess << endl;
        cout << "Id process: " << piForNotepad.dwProcessId << endl;
    }
 
    //*
    if(TerminateProcess(piForNotepad.hProcess, 0))
         cout << "Process successfully done!!!\n";
    //*/
 
    return 0;
}
в чем может быть проблема?
0
AlexVRud
442 / 152 / 38
Регистрация: 04.07.2014
Сообщений: 431
08.07.2014, 13:17 #20
Цитата Сообщение от vlinx Посмотреть сообщение
не создается файл example_dll.o
Попробуй задать полное имя выходного файла через ключ -o
0
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 13:23  [ТС] #21
Цитата Сообщение от AlexVRud Посмотреть сообщение
Попробуй задать полное имя выходного файла через ключ -o
так?
C++
1
TCHAR czCommandLine[] = "C:\\strawberry\\c\\bin\\g++ -c -DBUILDING_EXAMPLE_DLL D:\\example_dll.cpp -o example_dll example_dll.o";
все равно не создается
0
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
08.07.2014, 15:13 #22
vlinx, жестоко ты с ним, зачем же ты его убил, он даже сделать ничего не успел. Это я про TerminateProcess.
Надо было как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    PROCESS_INFORMATION processInformation;
    STARTUPINFO startupInfo;
    memset(&processInformation, 0, sizeof(processInformation));
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
 
    TCHAR czCommandLine[] = "g++ -c -DBUILDING_EXAMPLE_DLL -shared D:\\example.cpp -o D:\\example.dll";
    if(CreateProcess(NULL, czCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation))
    {
        std::cout << "Process " << czCommandLine << " successfully!\n";
        std::cout << "Descriptor process: " << processInformation.hProcess << std::endl;
        std::cout << "Id process: " << processInformation.dwProcessId << std::endl;
    }
 
    WaitForSingleObject(processInformation.hProcess, INFINITE);
    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);
}
1
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 16:38  [ТС] #23
DrOffset, действительно) спасибо!
сейчас попробую сделать чтобы было все динамически.

Добавлено через 47 минут
Получилось следующее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
 
using namespace std;
 
int main()
{
    //Загрузка введенного пользователем кода в строке
    std::string input_memo_text = "int get_my_inn(int x, int y){ int z = 4; return x * y - z; }";
    input_memo_text += "\n\r";
 
    //Парсим строку на объявление и определение
    std::size_t end_declaration_pos = input_memo_text.find_first_of("{");
    std::string declaration = input_memo_text.substr(0, end_declaration_pos) + ";\n";
    std::string definition = input_memo_text;
 
 
 
    //Сохранение кода в файлы .h .cpp для компиляции DLL
 
    //хедер
    ofstream dll_h;
    dll_h.open("D:\\example_dll.h", std::ios::out);
 
    dll_h << "#ifndef EXAMPLE_DLL_H #define EXAMPLE_DLL_H #ifdef __cplusplus extern \"C\" { #endif #ifdef BUILDING_EXAMPLE_DLL #define EXAMPLE_DLL __declspec(dllexport) #else #define EXAMPLE_DLL __declspec(dllimport) #endif #ifdef __cplusplus } #endif" << std::endl;
    dll_h << declaration << std::endl;
    dll_h << "#endif" << std::endl;
    dll_h.close();
 
 
 
    //cpp
    ofstream dll_cpp;
    dll_cpp.open("D:\\example_dll.cpp", std::ios::out);
 
    dll_cpp << "#include <iostream>" << std::endl;
    dll_cpp << "#include \"example_dll.h\"" << std::endl;
    dll_cpp << definition << std::endl;
    dll_cpp.close();
 
 
 
 
    //string path_compiler = "C:\\strawberry\\c\\bin\\g++.exe g++";
   // string cmd1 = "g++ -c -DBUILDING_EXAMPLE_DLL example_dll.cpp";
//*
 
    //Создание DLL
    STARTUPINFO startupInfo;
    PROCESS_INFORMATION processInformation;
 
    memset(&processInformation, 0, sizeof(processInformation));
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
 
 
    TCHAR czCommandLine1[] = "C:\\strawberry\\c\\bin\\g++ -c -DBUILDING_EXAMPLE_DLL D:\\example_dll.cpp -o D:\\example_dll.o";
    CreateProcess(NULL, czCommandLine1, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
    WaitForSingleObject(processInformation.hProcess, INFINITE);
 
    TCHAR czCommandLine2[] = "C:\\strawberry\\c\\bin\\g++ -shared -o D:\\example_dll.dll D:\\example_dll.o -Wl,--out-implib,D:\\libexample_dll.a";
    CreateProcess(NULL, czCommandLine2, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
    WaitForSingleObject(processInformation.hProcess, INFINITE);
 
 
    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);
 
 
    //И подгружаем  dll
    HINSTANCE h;
    int (*func_from_dll) (int, int);
 
    h = LoadLibrary("d:\\example_dll.dll");
 
    if (!h)
    {
        std::cout << "dll not found\n";
        return 5;
    }
 
    func_from_dll = (int (*) (int, int)) GetProcAddress(h, "get_my_inn");
 
    if (!func_from_dll)
    {
        printf("function not found\n");
        return 13;
    }
 
    int generated_value = func_from_dll(5,6);
 
    std::cout << generated_value << "\n !!!!!";
 
    FreeLibrary(h);
 
    return 0;
}
1) Сохраним код, который ввел пользователь в строку
2) Разобьем и запишем эту строку на определение и объявление введенной в MEMO ф-ии
3) Компилим DLL
4) Загрузка DLL и вызов ф-ии

Сейчас непойму, почему при компиляции dll выпадают ворнинги: extra tokens at #ifndef derective (example_dll.h) , то ли пробелы не нарвятся, то ли кодировка файла... в результате : function not found

Добавлено через 5 минут
и почему-то размер dll стал 471кб, а было 14
0
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
08.07.2014, 16:54 #24
Цитата Сообщение от vlinx Посмотреть сообщение
Сейчас непойму, почему при компиляции dll выпадают ворнинги:
Накосячил при формировании хедера.
Должно быть как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //хедер
    ofstream dll_h;
    dll_h.open("D:\\example_dll.h", std::ios::out);
 
    dll_h << "#ifndef EXAMPLE_DLL_H\n"
             "#define EXAMPLE_DLL_H\n"
             "#ifdef __cplusplus\n"
             "extern \"C\" {\n"
             "#endif\n"
          << declaration
          << "#ifdef __cplusplus\n"
             "}\n"
             "#endif\n"
             "#endif\n";
Добавлено через 9 минут
Цитата Сообщение от vlinx Посмотреть сообщение
и почему-то размер dll стал 471кб, а было 14
Из-за <iostream> в dll.
1
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 16:56  [ТС] #25
26! причем это день моего день рождения)) чисто случайно так совпало)))
супер.

кстати, DrOffset, при формировании хедера, я нетуда внес определение функции. А какие определения тогда можно вносить в ту секцию?
0
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
08.07.2014, 16:58 #26
Цитата Сообщение от vlinx Посмотреть сообщение
А какие определения тогда можно вносить в ту секцию?
В ту, это в какую?
0
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 17:02  [ТС] #27
Цитата Сообщение от DrOffset Посмотреть сообщение
В ту, это в какую?
Этот вариант сработал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    dll_h <<   "#ifndef EXAMPLE_DLL_H\n"
       "#define EXAMPLE_DLL_H\n"
 
       "#ifdef __cplusplus\n"
       "extern \"C\" {\n"
       "#endif\n"
 
       "#ifdef BUILDING_EXAMPLE_DLL\n"
       "#define EXAMPLE_DLL __declspec(dllexport)\n"
       "#else\n"
       "#define EXAMPLE_DLL __declspec(dllimport)\n"
       "#endif\n"
        << declaration << std::endl
       <<"#ifdef __cplusplus\n"
       "}\n"
       "#endif\n"
      "#endif\n" << std::endl;

Этот вариант не сработал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        dll_h <<   "#ifndef EXAMPLE_DLL_H\n"
       "#define EXAMPLE_DLL_H\n"
 
       "#ifdef __cplusplus\n"
       "extern \"C\" {\n"
       "#endif\n"
 
       "#ifdef BUILDING_EXAMPLE_DLL\n"
       "#define EXAMPLE_DLL __declspec(dllexport)\n"
       "#else\n"
       "#define EXAMPLE_DLL __declspec(dllimport)\n"
       "#endif\n"
 
       "#ifdef __cplusplus\n"
       "}\n"
       "#endif\n"
       << declaration
      <<"#endif\n" << std::endl;
во втором варианте - declaration в другом месте и не сработало
0
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
08.07.2014, 17:09 #28
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от vlinx Посмотреть сообщение
я нетуда внес определение функции.
Я понял. Да можно было и там оставить. Мне было просто лень все перепечатывать. Ошибка-то была из-за отсутствия переноса строк после директив.

Добавлено через 5 минут
Цитата Сообщение от vlinx Посмотреть сообщение
Этот вариант не сработал
А, ну надо функцию помечать как extern "C". Иначе ее имя будет декорировано как С++-сное (аргументы, спецификации исключений и т.п.). И выглядеть оно будет как-то так (это зависит от компилятора): Z10get_my_innii. extern "C" явно говорит о декорации в стиле С. В С нет перегрузок, исключений и т.п. фигни, поэтому имя функции - это только имя функции.
1
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
08.07.2014, 17:14  [ТС] #29
Возвращаясь к 4 нашим вариантам..
Получается вариант 3 практически реализован.

И у него 2 зависимости (в вызывающем коде):
1) Указатель на ф-ию (прототип)
2) Вызов ф-ии (тоже по прототипу нужно вызывать)

тут, я думаю, можно опять делать парсинг input_memo_text и считать кол-во и типы параметров и рез-тат ф-ии.
а ниже сделать некий switch по возможным вариантам...

вообщем пудумаю еще. отпишусь
0
DrOffset
7141 / 4282 / 964
Регистрация: 30.01.2014
Сообщений: 7,084
08.07.2014, 17:16 #30
vlinx, Кстати вот статья на тему декораций имен.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2014, 17:16
Привет! Вот еще темы с ответами:

Компиляция C++ кода через консоль - C++
Есть простенький код: #include &lt;iostream&gt; #include &lt;vector&gt; int main(int argc, char *argv){ std::vector&lt;int&gt; vec; int num=1;...

Компиляция кода... не могу сообразить. - C++
Доброго времени суток уважаемые форумчане! Прошу помочь с решением проблемы: есть исходники memtest86+, скачал чтоб разобраться как...

Компиляция кода под конкретную ОС - C++
Есть ОС Windows, Linux, Android. Хочу понять базовые знание по тому как делается библиотека работающая на всех ОС. Допустим пишем...

Компиляция кода с ромбовидным наследованием - C++
Здравствуйте. Я написал элементарное наследование. На VS 2015 всё компилится, а на CLion нет. В чём может быть проблема? class A { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.07.2014, 17:16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru