Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lua
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.53/17: Рейтинг темы: голосов - 17, средняя оценка - 4.53
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
1

vs c++ & lua

23.01.2012, 20:06. Просмотров 3085. Ответов 17
Метки нет (Все метки)

Здравствуйте, занимаюсь разработкой 3д игры, пишу движок и прочее, когда то модил сталкера, в плане скриптинга, уж очень нравилось и в программирование пришел именно через это, а теперь вот свое делаю, вроде все идет так как хочу, но есть НО, у себя в игре хочу использовать луа, причем так чтобы можно было экспортировать классы и функции из с++ в луа. Для этого как бэ есть готовые решения luabindы всякие и прочее, но использовать нормально луабинд у меня не получилось, уже матов не хватает, экспортировать классы отказывается, выдает ошибки с проблемами со стеком и адресами, исключениями, в общем муть всякая. Между делом искал что пишут про эти биндинги(luabind, tolua, tolua++, rlua и прочее), примерно 50/50 - те кто использует их и им нравятся, и тех кто использует самопальные, и им не нравятся эти луабинды и прочее. И пришла мысль, а что если самому попробовать сделать нечто вроде самопального биндинга? Возможно ли сделать самому качественный экспорт с++ классов, пространств имен и прочего в луа? Прошу опытных в этом деле высказаться по данной проблеме. Заранее спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2012, 20:06
Ответы с готовыми решениями:

Lua & bash
Всем привет! Появилась необходимость написания lua скрипта, в котором будет...

LUA + C++
Привет всем :) я чото не понимаю чо у меня выевляется ошибки luaavg.obj...

Быстродействие Lua
Мне не раз приходилось видеть, что ядро програмы написано на С++, а...

Установка Lua
Здравствуйте! Подскажите, пожалуйста как это сделать: Что бы вы могли...

Lua script
Расшифруйте пожалуйста

17
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 11:03  [ТС] 2
Оказывается можно, и не так уж и сложно.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 19:05 3
Это не ответ на поставленный вопрос, поскольку ты, судя по всему, с Lua работать умеешь. Но на всякий случай: http://www.cyberforum.ru/cpp-builder/thread68085.html

Если в данной теме будут получены конкретные ответы на конкретные вопросы, но надо будет подумать о том, чтобы эти две темы объединить
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 19:09  [ТС] 4
Evg, если надо, думаю что смогу выложить эту систему биндинга сюда, только немного подшаманить ее нужно.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 19:15 5
А можешь своими словами пояснить, что такое "биндинг" в контексте Lua. Потому что покопавшись в инете, я толком так и не понял
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 19:17  [ТС] 6
Evg, ну как бэ ... я скок читал про луа в интернете везде употребляется это слово, я не мог понять что это такое еще когда занимался моддингом сталкера, потом посмотрел в гугл переводчике перевод - "связка", ну вот потом то и понял что биндинг с++ и луа это связка работы с++ и луа ... как-то так.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 19:20 7
А в чём эта "связка" выражаться-то должна? Особенно учитывая то, что она есть изначально
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 19:24  [ТС] 8
К примеру помнишь я спрашивал как вызвать луа функцию, а ты написал пример как и + экспорт функции из с++ в луа? Ну дык все правильно было, но ведь это гемор передлывать все функции под луа, или вызов функции к примеру можно вообще одной строчкой сделать, регистрацию классов, функций,пространств имен, переменных можно делать гораздо проще с системой биндинга (я не говорю что моей ибо я ее делаю затачивая под свои нужды), как то так.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 19:47 9
В своей программе я сделал классы-обёртки. По возможности старался делать универсально, но у каждого разные понятия о том, как наиболее удобно работать с этим делом (в каком виде его реализовывать). В аттаче файлы, которые целиком выдраны из моей проги (а потому просто так они не скомпилятся, т.к. нужна реализация ASSERT)

Вся работа идёт в виде двух классов TLuaCaller и TLuaCallee. На тот случай, если не знаком с программерской терминологией, то "caller" - это тот, кто вызывает (функцию), а "callee" - это тот, кого вызывают

Пример использования. Не готовый пример 1 в 1 для запуска, а чисто для того, чтобы общий принцип показать. Ты вроде бы как в курсе проблемы, по идее тебе понятно будет.

Вызов функции Lua из кода на Си++

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
TLuaCaller *m_Caller = new TLuaCaller();
 
if (! m_Caller->LoadFile (file_name))
{
  // Ошибка
  return;
}
 
// Заводим глобальную переменную внутри контекста Lua
m_Caller->SetVarInteger ("LUA_VAR", 5);
 
// Регистрируем функцию на Си++, которую можно будет вызывать из Lua
// (тело функции описано ниже)
m_Caller->RegisterFunc ("CPP_FUNC", MyCppFunc);
 
// Вызов функции Lua с двумя параметрами (string, int) и одним результатом (int)
m_Caller->InitCall ("LUA_FUNC", 2, 1);
m_Caller->PassIntegerArg ("abc");
m_Caller->PassIntegerArg (5);
if (m_Caller->DoCall())
{
  // Вызов функции был удачный, читаем результат
  res = m_Caller->ReadIntegerRes();
} else
{
  // Были какие-то проблемы. Текст ошибки достаём через
  // m_Caller->GetCallErrorText()
}
m_Caller->FinishCall();
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Функция Си++, которая будет вызываться из кодов на Lua
// Полагаем, что у функции должно быть два параметра (int, string)
// и возвращаемый результат - string
int
MyCppFunc (lua_State *st)
{
  TLuaCallee callee(st);
 
  // Читаем аргументы
  ASSERT (callee.GetNumArgs() == 2);
  int arg1 = callee.GetIntegerArg (1);
  AnsiString arg2 = callee.GetStringArg (2);
 
  ...
 
  // Возвращаем рузультат. Наша функция возвращает количество результатов.
  // Класс TLuaCalee написан под то, что у функции может быть только один
  // результат. Потому что два и более результата пока мне не понадобилось
  callee.SetStringRes ("abc");
  return 1;
}
Понятно, что вариант через шаблон, как это написано тут, может оказаться более удобным для написания. Но меня больше устраивают варианты, когда нужно явно описывать тип аргумента. По крайней мере это страхует от того, что при copy-paste случайно не накосячишь по типу того, что вместо целого числа начнёшь передавать строку
0
Вложения
Тип файла: rar BaseLua.rar (3.8 Кб, 34 просмотров)
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 19:57  [ТС] 10
Evg, ну да, тебе так удобно, а мне вот удобно чтоб я эту функцию не переделывал, и одной строкой ее зарегистрировал и одной строкой вызвал функцию из луа и получил результат, у каждого разные вкусы, вот мой вариант, он очень громоздкий ибо показываю чтоб понять суть:
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
181
182
183
template <typename ReturnType, void* func,
                typename ArgType1 = nil_type, 
                typename ArgType2 = nil_type,
                typename ArgType3 = nil_type,
                typename ArgType4 = nil_type,
                typename ArgType5 = nil_type,
                typename ArgType6 = nil_type,
                typename ArgType7 = nil_type,
                typename ArgType8 = nil_type,
                typename ArgType9 = nil_type,
                typename ArgType10 = nil_type>
    class   ExportFunctionToLua
    {
    public:
 
        static int ExportFunction(lua_State*lua)
        {
            ArgType1    a1;
            ArgType2    a2;
            ArgType3    a3;
            ArgType4    a4;
            ArgType5    a5;
            ArgType6    a6;
            ArgType7    a7;
            ArgType8    a8;
            ArgType9    a9;
            ArgType10   a10;
            ReturnType  r;
 
                if(typeid(ArgType10) != typeid(nil_type))
                {   
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5,ArgType6,ArgType7,ArgType8,ArgType9,ArgType10);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    FromLua(L, 6, &a6);
                    FromLua(L, 7, &a7);
                    FromLua(L, 8, &a8);
                    FromLua(L, 9, &a9);
                    FromLua(L, 10, &a10);
                    r = Function (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
                }
                else if(typeid(ArgType9) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5,ArgType6,ArgType7,ArgType8,ArgType9);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    FromLua(L, 6, &a6);
                    FromLua(L, 7, &a7);
                    FromLua(L, 8, &a8);
                    FromLua(L, 9, &a9);
                    r = Function (a1,a2,a3,a4,a5,a6,a7,a8,a9);
                }
                else if(typeid(ArgType8) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5,ArgType6,ArgType7,ArgType8);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    FromLua(L, 6, &a6);
                    FromLua(L, 7, &a7);
                    FromLua(L, 8, &a8);
                    r = Function (a1,a2,a3,a4,a5,a6,a7,a8);
                }
                else if(typeid(ArgType7) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5,ArgType6,ArgType7);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    FromLua(L, 6, &a6);
                    FromLua(L, 7, &a7);
                    r = Function (a1,a2,a3,a4,a5,a6,a7);
                }
                else if(typeid(ArgType6) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5,ArgType6);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    FromLua(L, 6, &a6);
                    r = Function (a1,a2,a3,a4,a5,a6);
                }
                else if(typeid(ArgType5) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4,ArgType5);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
                    FromLua(L, 5, &a5);
                    r = Function (a1,a2,a3,a4,a5);
                }
                else if(typeid(ArgType4) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3,ArgType4);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    FromLua(L, 4, &a4);
 
                    r = Function (a1,a2,a3,a4);
                }
                else if(typeid(ArgType3) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2,ArgType3);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    FromLua(L, 3, &a3);
                    r = Function (a1,a2,a3);
                }
                else if(typeid(ArgType2) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1,ArgType2);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    FromLua(L, 2, &a2);
                    r = Function (a1,a2);
                }
                else if(typeid(ArgType1) != typeid(nil_type))
                {
                    typedef ReturnType (*ExportingFunction)(ArgType1);
 
                    ExportingFunction Function = (ExportingFunction)func;
            
                    FromLua(L, 1, &a1);
                    r = Function (a1);
                }
                else //функция без аргументов
                {
                    typedef ReturnType (*ExportingFunction)();
 
                    ExportingFunction Function = (ExportingFunction)func;
                    r = Function ();
                }
                
                if(typeid(ReturnType) != typeid(nil_type))
                    ToLua(lua,r);
            return 1; 
        }
        
        void RegFunction(lua_State* lua,const char * name)
        {
            lua_register (lua,name,ExportFunction);
        }
}
Вот как регистрирую:
C++
1
SXBindLua::ExportFunctionToLua<SXBindLua::nil_type, (void*)(PrintInfoLogScripts), const char*>().RegFunction(L,"PrintLog");
Вызов функции примерно такой же, позже покажу если интересно.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 20:21 11
Цитата Сообщение от Byurrer Посмотреть сообщение
а мне вот удобно чтоб я эту функцию не переделывал
"Эту" - это какую

Цитата Сообщение от Byurrer Посмотреть сообщение
одной строкой ее зарегистрировал
Да регистрировать и у меня одной строкой. Другое дело, что доставать параметры и отдавать результат - как бы лишние строки возникают


При такой реализации через шаблон невозможно сделать чёткий run-time контроль за передаваемыми типами. Другими словами, стоит выбор между тем, чтобы сэкономить 2-3-4 строки на вызове функций и тем, чтобы сделать систему с надёжным контролем. Мой программерский опыт уже давно показал, что выражение "краткость - сестра таланта" в случае программирования почти никогда себя не оправдывает и ни капельки не раздумывая отказался от реализации через шаблоны

В моей реализации для повторения шаблонного варианта (т.е. сокращения кода) я бы в TLuaCaller добавил методы типа DoCalIntIntString (вызвать функцию с результатом Int и аргументами Int, String). Потому как в "обычном" случая среди множества всех прототипов навряд ли наберётся хотя бы два десятка разных, а потому допиливание напильником будет не более 20 лишних методов. Правда для TLuaCalee я пока не вижу подобных решений.

Добавлено через 1 минуту
Кстати, в твоём варианте только способ вызова функций Си++ из Lua. Для полноты картины показал бы и вызов функций Lua из Си++ (он поинтереснее будет )
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 20:29  [ТС] 12
Evg, как бэ вот, тож громоздкий, еще не оптимизировал но думаю суть ясна будет:
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
template<typename ReturnType,
                class Arg1 = nil_type,
                class Arg2 = nil_type,
                class Arg3 = nil_type,
                class Arg4 = nil_type,
                class Arg5 = nil_type,
                class Arg6 = nil_type,
                class Arg7 = nil_type,
                class Arg8 = nil_type,
                class Arg9 = nil_type,
                class Arg10 = nil_type>
    class CallFunction
    {
    public:
 
        ReturnType Call(lua_State* L,const char* name_func,const char* file, //для отчета
                        Arg1 a1 = nil_var,Arg2 a2 = nil_var,Arg3 a3 = nil_var,Arg4 a4 = nil_var,Arg5 a5 = nil_var,
                        Arg6 a6 = nil_var,Arg7 a7 = nil_var,Arg8 a8 = nil_var,Arg9 a9 = nil_var,Arg10 a10 = nil_var)
        {
            void *value = 0;
            lua_pcall (L, 0, 0, 0);
            int CountArgs = 0;
            lua_getfield (L, LUA_GLOBALSINDEX, name_func);
                if(typeid(a1) != typeid(nil_type))
                {
                    ToLua(L, a1);
                    CountArgs++;
                }
                if(typeid(a2) != typeid(nil_type))
                {
                    ToLua(L, a2);
                    CountArgs++;
                }
                if(typeid(a3) != typeid(nil_type))
                {
                    MessageBox(0,0,0,0);
                    ToLua(L, a3);
                    CountArgs++;
                }
                if(typeid(4) != typeid(nil_type))
                {
                    ToLua(L, a4);
                    CountArgs++;
                }
                if(typeid(a5) != typeid(nil_type))
                {
                    ToLua(L, a5);
                    CountArgs++;
                }
                if(typeid(a6) != typeid(nil_type))
                {
                    ToLua(L, a6);
                    CountArgs++;
                }
                if(typeid(a7) != typeid(nil_type))
                {
                    ToLua(L, a7);
                    CountArgs++;
                }
                if(typeid(a8) != typeid(nil_type))
                {
                    ToLua(L, a8);
                    CountArgs++;
                }
                if(typeid(a9) != typeid(nil_type))
                {
                    ToLua(L, a9);
                    CountArgs++;
                }
                if(typeid(a10) != typeid(nil_type))
                {
                    ToLua(L, a10);
                    CountArgs++;
                }
 
            int ResRun = lua_pcall(L, CountArgs, 1, 0);
 
                if (ResRun != 0)    //!!!Run-time Lua error
                {
                    LogFatal("С++ файл генератор ошибки: " + ToString(__FILE__) + " строка: " + ToString(__LINE__));
                    LogFatal("Ошибка при выполнении кода скрипта: " + ToString(file));
                    LogFatal("Отчет об ошибке: Run-time Lua error - " + ToString(lua_tostring (L, -1)));
                    SendMessage(FindWindow("SkyX",0), WM_SYSCOMMAND, SC_MINIMIZE, 0);
                    MessageBox(0,ToPointChar(ToString("С++ файл генератор ошибки: " + ToString(__FILE__) + " строка: " + ToString(__LINE__) + "\n") + "Во время выполения кода скрипта было совершена ошибка, отчет lua:\n" + "Run-time Lua error: " + ToString(lua_tostring (L, -1)) + "\nНеобходимо завершить работу программы. Вся информация находится по адресу:\n" + ToString(Pather::CutPath()) + "\\log.txt"),"SkyX Engine - Run-time Lua error",MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
                    exit(0);
                    MessageBox(0,ToPointChar("Run-time Lua error: " + ToString(lua_tostring (L, -1))),"Run-time error",0);
                }
            
                if(lua_isnumber(L, 1))
                {
                    ReturnType *num = new ReturnType;
                        if(typeid(ReturnType) == typeid(float) || typeid(ReturnType) == typeid(double))
                            *num = lua_tonumber(L, 1);
                        else
                            *num = lua_tointeger(L, 1);
                    value = num;
                }
                else if(lua_isstring(L, 1))
                {
                    const char *str = new char;
                    str = lua_tostring(L, 1);
                    value = (void*)str;
                }
                else if(lua_iscfunction(L, 1))
                {
                    lua_CFunction func = lua_tocfunction(L, 1);
                    value = (void*)func;
                }
                else if(lua_isboolean(L, 1))
                {
                    bool *bf = new bool;
                    *bf = lua_toboolean(L, 1);
                    value = (void*)bf;
                }
 
 
            ReturnType Return;
                if(typeid(ReturnType) == typeid(nil))
                    value = &nil_var;
 
            Return = *(ReturnType*)(value);
            return Return;
        }
    };
Вот как вызываю:
C++
1
int ret = SXBindLua::CallFunction<int,int,int>().Call(L,"add","test.script",5,5);
Добавлено через 2 минуты
"Эта функция" - любая функция, кроме нестатической функции-члена класса.

Добавлено через 1 минуту
С предыдущим кодом можно экспортировать как возвращающие функции так и void, указав в аргументах шаблона nil
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 20:36 13
Цитата Сообщение от Byurrer Посмотреть сообщение
Evg, как бэ вот, тож громоздкий
Ну понятно, что без громоздкости тут никак

1. Шо такое ToLua?
2. Внутри твоего шаблонного класса обрабатывать ошибки неправильно. Ошибку нужно отдавать наверх, и там её обрабатывать. Т.е. внизу делают, наверху думают

Ну а в качестве рабочей версии оба твоих шаблона вполне приемлимы
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 20:41  [ТС] 14
Цитата Сообщение от Evg Посмотреть сообщение
внизу делают, наверху думают
оно везде так ... даж в государстве, кто нами управляет думает а мы делаем ...
ToLua - эту идейку я позаимствовал с одного сайта, помещает значение на вершину стека
Цитата Сообщение от Evg Посмотреть сообщение
Внутри твоего шаблонного класса обрабатывать ошибки неправильно
поясни пожалуйста, не могу догнать, вот если ошибка в скрипте и обойти ее никак то программа сообщает об этом юзеру и заввершает свою работу, что не так? Или я не так что понял?
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 21:21 15
Цитата Сообщение от Byurrer Посмотреть сообщение
ToLua - эту идейку я позаимствовал с одного сайта, помещает значение на вершину стека
Всмысле это ещё один шаблон? Т.е. чтобы заработала твоя технология, надо ещё что-то чужое подцепить?

Цитата Сообщение от Byurrer Посмотреть сообщение
поясни пожалуйста, не могу догнать, вот если ошибка в скрипте и обойти ее никак то программа сообщает об этом юзеру и заввершает свою работу, что не так?
Ты пишешь, условно говоря, универсальную компоненту, которая никак не зависит от конкретной реализации программы. А потому в случае ошибки надо уметь каким-то образом возвращать информацию о том, что произошла ошибка. В моём варианте это определяется по результату вызова метода DoCall (есть ошибка, нет ошибки).

Ну или чтобы стало ясно, более ощутимый пример. Когда ты открываешь файл, то в случае отсутствия файла тебе системные функции каким-то образом возвращают информацию о том, что файл отсутствует. А ты (как программист, а не как пользователь), уже сам решаешь, что делать в этом случае. Согласись, было бы совсем дебильно, если бы функция open или fopen в случае отсутствия файла печатала на экран текст ошибки и завершала работу программы. Внизу только делают и возвращают результат наверх. А наверху думают, что с этим результатом делать. Это справедливо не только в luabind'ах, но и при реализации любого интерфейса, претендующего на универсальность хотябы в минимальной степени

В твоём случае очевидным и общепринятым (но на мой взгляд идиотским) решением было бы сделать throw и пусть наверху это дело ловят.
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 21:30  [ТС] 16
Evg, нет, несколько перегруженных функций типа так:
C++
1
2
3
4
5
6
7
8
9
void ToLua(lua_State*lua,const char *arg)
{
    lua_pushstring(lua,arg);
}
 
void ToLua(lua_State*lua,int arg)
{
    lua_pushinteger(lua,arg);
}
и так далее, мне кажется это более эффективно нежели выбор.
На счет ошибки ... я подумаю, хотя скриптов которые будут вызываться из движка не так и много будет ... буду думать.

Добавлено через 1 минуту
На счет универсальности ... затачиваю под себя ... а в плане программирования я очень придирчив ... поэтому стараюсь.
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
01.02.2012, 21:40 17
Цитата Сообщение от Byurrer Посмотреть сообщение
Evg, нет, несколько перегруженных функций типа так
А, ну да, я тормоз

Цитата Сообщение от Byurrer Посмотреть сообщение
На счет универсальности ... затачиваю под себя
Даже если затачиваешь, то с сточки зрения проектирования программы такое поведение всё равно является некорректным. Пока программы маленькие и простенькие - оно сойдёт. Если программы большие - то оно рано или поздно аукнется.
0
Byurrer
2 / 2 / 0
Регистрация: 09.04.2011
Сообщений: 110
01.02.2012, 21:42  [ТС] 18
Evg, учту замечание.
0
01.02.2012, 21:42
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2012, 21:42

Парсинг lua
Здравствуйте форумчане,меня озадачило такой задачей,нужно из текста Client...

Парсер на lua
Тут описано как подключить и использовать и библиотеку для языка lua...

Скрипты lua
Вопрос: вот я у себя на хабе (дсс) настроил викторину, а как мне сделать чтобы...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

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