Здравствуйте, yxiie, Вы писали:
Y>Здравствуйте, _Winnie, Вы писали: Y>если ты ще eval к С++ прикрутишь, я буду хлопать стоя
С перлом дела не имел, до такой штуки как eval не дошел
Можно было бы скомпилировать не dll, а exe, и звать не функцию из dll, а целиком программу.
Но если надо часто звать, то выгодней dll — почти без накладных расходов, оптимизированый С++ом код.
Я слышал, что некоторые таким образом делали "Скрипты на С++" в своих играх.
вот пример общения с моей программой:
c:\projects\test2\test_dll_eval>exe.exe
enter function 'F': (type "#end" to run function)
#include <windows.h>
#include <string>
int F(std::string message) { return MessageBox(0, message.c_str(), message.c_str(), MB_OK); } //показываю пользователю MessageBox
#end
dll.cpp
dll.cpp(47) : warning C4273: 'StringCat' : inconsistent dll linkage
Creating library dll.lib and object dll.exp
enter parameter for function:
hello,world
result of invocation: 1
enter function 'F': (type "#end" to run function)
#include <math.h>
float F(float rrr) { return sqrtf(rrr); }
#end
dll.cpp
dll.cpp(47) : warning C4273: 'StringCat' : inconsistent dll linkage
Creating library dll.lib and object dll.exp
enter parameter for function:
2
result of invocation: 1.41421
enter function 'F': (type "#end" to run function)
c:\projects\test2\test_dll_eval>exe.exe
enter function 'F': (type "#end" to run function)
int F(int i) { return i+2; }
#end
dll.cpp
dll.cpp(45) : warning C4273: 'StringCat' : inconsistent dll linkage
Creating library dll.lib and object dll.exp
enter parameter for function:
3
result of invocation: 5
enter function 'F': (type "#end" to run function)
^C
Это код, наверное, довольно некачественный — какой-то непонятный warning.
И у меня глаза слыпаются, так что прошу простить за допущенные небрежности.
файл exe.cpp
/*
cl /I%BOOST% /EHsc exe.cpp dll.lib
*/#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using std::string;
typedef const char *(__cdecl *pfStringCat)(const char *s);
pfStringCat StringCat;
#include <iostream>
#include <fstream>
#include <iterator>
string GetProgram()
{
std::cout <<"enter function 'F': (type \"#end\" to run function)\n";
string program, line;
do
{
(program += line) += '\n';
std::getline(std::cin, line);
} while (line != "#end");
return program;
}
#include <process.h>
void CompileProgram(const string &program)
{
std::ifstream dll_tail_stream("dll_tail.cpp");
if (!dll_tail_stream)
std::cerr <<"can't open file dll_tail.cpp\n";
string dll_tail;
for (;;)
{
int c = dll_tail_stream.get();
if (c == EOF)
break;
dll_tail += char(c);
}
{
std::ofstream dll_source("dll.cpp");
dll_source << program << dll_tail;
}
if (0 != system("cl /EHsc dll.cpp /link /dll kernel32.lib user32.lib gdi32.lib /nologo /implib:dll.lib /out:dll.dll"))
{
std::cout <<"can't compile program\n";
}
}
void Run(const string ¶m)
{
struct Dll
{
HINSTANCE h;
Dll() { h = LoadLibrary("dll.dll"); }
~Dll() { if(h) FreeLibrary(h); }
} dll;
if (!dll.h)
{
std::cout <<"LoadLibrary failed";
return;
}
StringCat = (pfStringCat)GetProcAddress(dll.h, "StringCat");
if (!StringCat)
{
std::cout <<"GetProcAddress failed";
return;
}
std::cout <<StringCat(param.c_str()) <<'\n';
}
int main()
{
for (;;)
{
CompileProgram(GetProgram());
string param;
std::cout <<"enter parameter for function:\n";
std::cin >> param;
std::cout <<"result of invocation: ";
Run(param);
}
}
файл dll_tail.cpp
//DLL thunk template#include <string>
#include <sstream>
#include <stdexcept>
#include <iostream>
using std::string;
template <class R, class P>
string StringMouse(string s)
{
P p;
std::istringstream param(s);
if (!(param >> p))
throw std::runtime_error("can't convert " + s + "to type " + typeid(P).name());
R r = F(p);
std::ostringstream result;
result << r;
return result.str();
}
// выводим тип параметра и возвращаемого значения, исходя из типа указателя на функцию F
// возвращам указатель на функцию, которая конвертит строки туда-сюда, вызывая при этом F template <class R, class P>
string (*StringDog(R(*)(P)))(string)
{
return &StringMouse<R, P>;
}
//
//extern "C" __declspec(dllimport)
//const char *StringCat(const char *s);extern"C"__declspec(dllimport)
const char *__cdecl StringCat(const char *s);
extern"C"const char *__cdecl StringCat(const char *s)
try
{
static string result; //опасно, да. не надо так делать. Ну не надо...
result = StringDog(F)(s);
return result.c_str();
}
catch (std::exception &err)
{
std::cout << err.what();
return"";
}
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Надругательство над С++. Пожалуйста, не бейте меня.
Здравствуйте, _Winnie, Вы писали:
_W>Можно было бы скомпилировать не dll, а exe, и звать не функцию из dll, а целиком программу. _W>Но если надо часто звать, то выгодней dll — почти без накладных расходов, оптимизированый С++ом код.
Компилируемый из пользовательского ввода исполняемый код… Брррр. В таких вещах нужно очень сильно о безопасности подумать.
Re[4]: Надругательство над С++. Пожалуйста, не бейте меня.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, _Winnie, Вы писали:
_W>>Можно было бы скомпилировать не dll, а exe, и звать не функцию из dll, а целиком программу. _W>>Но если надо часто звать, то выгодней dll — почти без накладных расходов, оптимизированый С++ом код.
C>Компилируемый из пользовательского ввода исполняемый код… Брррр. В таких вещах нужно очень сильно о безопасности подумать.
да, вся эта ветка, читый прикол, никто не призывает к практическому применению этой жути
в общем мое мнение такое: эту ветку давно пора в "юмор".
... << RSDN@Home 1.1.3 stable >>
Re[5]: Надругательство над С++. Пожалуйста, не бейте меня.
Здравствуйте, yxiie, Вы писали:
Y>да, вся эта ветка, читый прикол, никто не призывает к практическому применению этой жути Y>в общем мое мнение такое: эту ветку давно пора в "юмор".
Могут не понять
1-й пост, да — сферический конь, по-сути. А второй — уже вполне пригодная для использования вещь...
Правильно работающая программа — просто частный случай Undefined Behavior
Re[4]: Надругательство над С++. Пожалуйста, не бейте меня.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, _Winnie, Вы писали:
_W>>Но если надо часто звать, то выгодней dll — почти без накладных расходов, оптимизированый С++ом код.
C>Компилируемый из пользовательского ввода исполняемый код… Брррр. В таких вещах нужно очень сильно о безопасности подумать.
Зависит от области применения и задач.
Правильно работающая программа — просто частный случай Undefined Behavior