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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ SDL2 BlitScaled и прозрачность - масштабирование изображения http://www.cyberforum.ru/cpp-beginners/thread1223906.html
Здравствуйте. Пару дней назад начал работать с SDL2, возникла некоторая проблема, никак не могу масштабировать изображение с прозрачностью. /* * File: main.cpp * Author: vortex * * Created on 7 Июль 2014 г., 0:23 */ #include <iostream> #include "SDL2/SDL.h"
C++ Как прочитать числа из бинарного файла Нужна помощь. Пытаюсь читать из бинарного файла простые числа, но ничего не читается. Файл взят тут, там же и его описание, через Hex editor он просматривается. Мой код: #include <iostream> std::ifstream primes("primes.32b", std::ios::binary); char buf; primes.getline(buf,4); std::cout<<" buf = "<<buf<<std::endl; Вы водится символ сердечка и всё. http://www.cyberforum.ru/cpp-beginners/thread1223905.html
C++ Преобразовать любое значение в строку
Привет. У меня есть примерно такая функция: template<typename T> std::string ToString(T value) { return std::to_string(value); }она работает на стандартных типах, ну это понятно. Как сделать чтобы код хотя бы мог компилироваться, если я передам в нее (в эту функцию) например свой класс? Спасибо. error C2665: 'std::to_string' : none of the 9 overloads could convert all the argument types
C++ Написать программу, вычисляющую функцию, представленную в виде ряда с заданной точностью
Ребят помогите пожалуйста. Написать на языке СИ++ Составить программу, которая рассчитывает таблицу значений этой функции в указанном диапазоне значений x0 — xk с заданным шагом h. Величины x0, xk, h вводить с клавиатуры. представленную в виде ряда с заданной точностью e=0,001. / С++ для начинающих
C++ Некорректная работа операции сложения векторов в классе http://www.cyberforum.ru/cpp-beginners/thread1223879.html
Объясните мне пожалуйста, почему операция сложения векторов работает неккоректно! Дело в том, что после выполнения операции, каким-то чудом изменяется и вектор и при выводе векторов один вектор изменяется(его координаты становится ужасными числами...) Я никак не меняю сами векторы, так в чем проблема? Вот код: Это 1 файл odm.cpp #include "odm.h" #include "math.h" int odm::kol=0;
C++ Построение логического вектора по правилу Помогите пожалуйста с задачкой. Даны действительные x и матрица A(n,n), n<=20. Разработать программу которая строит логический вектор X(n) по правилу: если максимальный элемент i-той строки не превышает х, тогда Х(і)=true, иначе - Х(і)=false. подробнее

Показать сообщение отдельно
vlinx
1 / 1 / 0
Регистрация: 27.06.2014
Сообщений: 74
09.07.2014, 21:12  [ТС]     Компиляция исходного кода в работающей программе
Цитата Сообщение от DrOffset Посмотреть сообщение
А тут проще заюзать готовый
тобишь вариант 4?

я его реализую тоже, но сначала этот до конца доведу.

Добавлено через 22 часа 21 минуту
Реализация варианта 3 (создание процесса с генерацией dll по шаблону) получилась следующая:
так как эта функция(возможность компиляции пользовательского кода) часть приложения, код в стиле ООП.

cAlgorithmGen.h
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
#ifndef CALGORITHMGEN_H
#define CALGORITHMGEN_H
 
#include <windows.h>
#include <TCHAR.H>
#include <sstream>
#include <iostream>
#include <fstream>
#include <string>
 
//генерация данных по
//пользовательскому алгоритму
class cAlgorithmGen //:public cUserGen //:public IGenerator
{
public:
 
    cAlgorithmGen(const std::string& memo_text,
                  const std::string& dll_name,
                  const std::string& workspace,
                  const std::string& compiler_path);
 
    ~cAlgorithmGen();
 
public:
    std::string next_value( int param1 = 0,
                            int param2 = 0,
                            int param3 = 0,
                            int param4 = 0,
                            const std::string& param5 = "null");
 
private:
    cAlgorithmGen();
 
    void prepare_files();
    void compile_dll();
 
    std::string get_declaration();
    std::string get_definition();
 
    std::string int2str(int x);
 
private:
    HINSTANCE h;
    int (*func_from_dll) (int, int, int, int, const std::string&);
    std::string m_memo_text;
    std::string m_dll_name;
    std::string m_workspace;
    std::string m_compiler_path;
};
 
#endif // CALGORITHMGEN_H

cAlgorithmGen.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include "cAlgorithmGen.h"
 
 
/*
cAlgorithmGen::cAlgorithmGen()
    :m_memo_text(""),
     m_dll_name(""),
     m_workspace(""),
     m_compiler_path("")
{
 
}
*/
 
 
cAlgorithmGen::cAlgorithmGen(const std::string& memo_text,
                             const std::string& dll_name,
                             const std::string& workspace,
                             const std::string& compiler_path)
    :h(0),
     func_from_dll(0),
     m_memo_text(memo_text),
     m_dll_name(dll_name),
     m_workspace(workspace),
     m_compiler_path(compiler_path)
{
    prepare_files();
    compile_dll();
 
 
    std::string dll_full_path = m_workspace + m_dll_name + ".dll";
 
    //подгружаем  dll
    h = LoadLibrary(dll_full_path.c_str());
    if (!h)
    {
        std::cerr<< "dll not found\n";
        return;
    }
 
    //call function from dll
    func_from_dll = (int (*) (int, int, int, int, const std::string&)) GetProcAddress(h, "main"); //dependence2
 
    if (!func_from_dll)
    {
        std::cerr << "function not found\n";
        return;
    }
}
 
 
cAlgorithmGen::~cAlgorithmGen()
{
    FreeLibrary(h);
 
    h = 0;
    func_from_dll = 0;
}
 
 
 
std::string cAlgorithmGen::next_value(int param1,
                                      int param2,
                                      int param3,
                                      int param4,
                                      const std::string& param5)
{
    int generated_value = func_from_dll(param1,
                                        param2,
                                        param3,
                                        param4,
                                        param5); //dependence3
 
    return int2str(generated_value);
}
 
 
 
void cAlgorithmGen::prepare_files()
{
    //Сохранение кода в файлы .h .cpp для компиляции DLL
 
    std::ofstream dll_h;
    dll_h.open((m_workspace + m_dll_name + ".h").c_str(), std::ios::out);
 
    dll_h <<"#ifndef EXAMPLE_DLL_H\n" //fix
            "#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"
            << get_declaration() << "\n"
            <<"#ifdef __cplusplus\n"
            "}\n"
            "#endif\n"
            "#endif\n";
 
    dll_h.close();
 
 
 
    std::ofstream dll_cpp;
    dll_cpp.open((m_workspace + m_dll_name + ".cpp").c_str(), std::ios::out);
 
    dll_cpp << "#include <iostream>" << std::endl;
    dll_cpp << "#include \"" + m_dll_name + ".h\"\n";
    dll_cpp << get_definition() << "\n";
    dll_cpp.close();
}
 
 
void cAlgorithmGen::compile_dll()
{
    STARTUPINFO startupInfo;
    PROCESS_INFORMATION processInformation;
 
    memset(&processInformation, 0, sizeof(processInformation));
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
 
 
 
    std::string c1 = m_compiler_path + " " + "-c -DBUILDING_EXAMPLE_DLL" + " " + m_workspace + m_dll_name + ".cpp" + " -o " + m_workspace + m_dll_name + ".o";
    TCHAR *czCommandLine1 = new TCHAR[c1.size() + 1]; //TCHAR - макрос, для независимости от кодировок
    czCommandLine1[c1.size()] = 0;
    std::copy(c1.begin(), c1.end(), czCommandLine1);
 
    CreateProcess(NULL, czCommandLine1, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
    WaitForSingleObject(processInformation.hProcess, INFINITE);
 
 
 
    std::string c2 = m_compiler_path + " " + "-shared -o " + m_workspace + m_dll_name + ".dll " + m_workspace + m_dll_name + ".o -Wl,--out-implib," + m_workspace + "libexample_dll.a";
    TCHAR *czCommandLine2 = new TCHAR[c2.size() + 1];
    czCommandLine2[c2.size()] = 0;
    std::copy(c2.begin(), c2.end(), czCommandLine2);
 
    CreateProcess(NULL, czCommandLine2, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
    WaitForSingleObject(processInformation.hProcess, INFINITE);
 
 
    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);
 
    delete czCommandLine1;
    delete czCommandLine2;
}
 
 
std::string cAlgorithmGen::get_declaration()
{
    std::size_t end_declaration_pos = m_memo_text.find_first_of(")");
    std::string declaration = m_memo_text.substr(0, end_declaration_pos + 1) + ";";
    std::cout << "DECL: " << declaration << "\n";
 
    return declaration;
 
}
 
 
std::string cAlgorithmGen::get_definition()
{
    std::size_t end_declaration_pos = m_memo_text.find("main");
    std::string definition = m_memo_text.substr(end_declaration_pos - 4, m_memo_text.size() - 1);
    std::cout << "DEFF: " << definition << "\n";
 
    return definition;
}
 
 
std::string cAlgorithmGen::int2str(int x)
{
    std::ostringstream result;
    result << x;
    return result.str();
}


Допустим в приложении(в моем) нет нужного генератора данных, и нужно задать свои правила генерации определенных значений.
Например:
-Сгенерировать 10 значений начиная с "0" с шагом 3, и вывести на экран\файл.

Для этой цели использование класса будет следующим:
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
#include "cAlgorithmGen.h"
 
using namespace std;
 
int main()
{
    /************************input data*********************************************/
 
    std::string compiler_path = "C:\\strawberry\\c\\bin\\g++";
    std::string dll_name = "example_dll";
    std::string workspace = "D:\\test_dll_ias\\";
 
    //Загрузка в строку введенного пользователем кода
    //std::string input_memo_text = "int get_my_inn(int x, int y){ int z = 4; return x * y - z; }";
    std::string input_memo_text = "static int kk = 0; int main(int x1, int x2, int x3, int x4, const std::string&){ int tmp = kk + x1;kk += x2; return tmp;}";
 
    /************************create data generator**********************************/
 
    cAlgorithmGen* gena1 = new cAlgorithmGen(input_memo_text,
                                             dll_name,
                                             workspace,
                                             compiler_path);
 
 
    /************************start data generator***********************************/
 
    int start_value = 0;
    int step = 3;
 
    for(int i = 0; i < 10; ++i)
    {
        std::cout << gena1->next_value(start_value, step) << "\n";
    }
 
 
    delete gena1;
    gena1 = 0;
 
    return 0;
}
Получаем значения: 0,3,6,9..27, которые уже можем использовать где требуется.



При такой реализации оснавная проблема - в зависимости шаблона прототипа функции в dll и прототипа вызова ф-ии в коде. Они должны совпадать.
Здесь решил использовать только 1 шаблон:
C++
1
int (*func_from_dll) (int, int, int, int, const std::string&);
тем самым предоставив пользователю 5 параметров. Можно использовать любой на выбор. Это накладывает ограничение на прототип ф-ии, который пользователь введет в поле MEMO - прототип будет всегда такой.

За генерацию следующего конкретного значения на каждом цикле генератора отвечает метод
C++
1
next_value()
это обертка для вызова ф-ии dll с аргументами по умолчанию. Аргументы по умолчанию введены - для удобства использования только нужного кол-ва параметров из 5 предложенных.

Добавлено через 5 часов 23 минуты
оказывается LoadLibrary нужно передавать unicode-строку

нужно заменить кусок на

C++
1
2
3
4
5
    std::string dll_full_path = m_workspace + m_dll_name + ".dll";
    std::wstring w_dll_full_path = std::wstring(dll_full_path.begin(), dll_full_path.end());
 
    //подгружаем  dll
    h = LoadLibrary(w_dll_full_path.c_str());
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru