Взаємодія chaiscript з c ++: контейнери, модулі і багатопоточність

Відео: 02 - Нить в C / C ++. Контейнери. Розумні покажчики. Аллокатори

Повернення значень і реєстрація контейнерів
Взаємодія ChaiScript з C ++: контейнери, модулі і багатопоточність

Щоб в основній програмі на С ++ отримати з інтерпретатора ChaiScript якесь значення, використовується метод eval:
ChaiScript chai;
cout lt; lt; chai.eval( "1 + 3") lt; lt; endl- // Друкує 4

З інтерпретатора можна отримувати покажчики на оголошені там функції (навіть анонімні):
chai ( "var f = fun (a, b) {a + b}") - // Створюємо функцію в ChaiScript
// Отримуємо покажчик на неї
boost :: function f = chai.eval ( "f") -
cout lt; lt; f (2,5) lt; lt; endl- // Викликаємо функцію в С ++

Ідилія закінчується, коли доводиться повертати з ChaiScript вектори:
chai ( "vec = [1,2,3,4]");
vector vec = chai.eval gt; ( "vec");
terminate called after throwing an instance of `chaiscript :: exception :: bad_boxed_cast`
what (): Can not perform boxed_cast

Проблема легко з`ясовна: вектор в ChaiScript - це vector, а нам потрібен vector.

Для С ++ це абсолютно різні типи, а перетворити один в інший можна тільки поелементно, що дуже занадто багато роботи. У цієї проблеми є просте рішення - зареєструвати в інтерпретаторі тип vector
.

Для цього навіть є спеціальна функція:
chai.add (bootstrap :: standard_library :: vector_type
lt; std :: vector
gt; ( "Vector_int")) -
chai ( "var vec1 = Vector_int ()") - chai ( "vec1.push_back (11)");
vector
vec1 = chai.eval gt; ( "vec1") - // Працює!



Таким чином можна додавати вектори будь-яких об`єктів. Також є аналогічні функції map_type для типів std :: map та list_type для std :: list. При цьому, на жаль, втрачається зручний синтаксис ініціалізації масивів на льоту.

Розглянута вище функція bootstrap :: standard_library :: vector_type і приклади її використання в документації ніде не описані. Її можна «відкопати» тільки в анотаціях до вихідних кодів і на форумі. І для ChaiScript це звичайна ситуація ...

Цінним джерелом інформації в таких випадках є юніт-тести ChaiScript в директорії unittests. Переглядаючи їх можна, наприклад, дізнатися, що в ChaiScript існують досить розвинені засоби інтроспекції і відображення, які також ніяк не задокументовані.

Модулі та багатопоточність

Інтерпретатор ChaiScript може без проблем викликатися з різних потоків, якщо при компонуванні використовується бібліотека Boost.thread. Приклад такого виклику знаходиться в файлі src / multithreaded.cpp.

У багатопотоковому режимі інтерпретатор працює повільніше, але на практиці це зазвичай не помітно, оскільки все одно всі виклики переадресовуються функцій С ++. Реалізацією многопоточности ChaiScript вигідно відрізняється від інших вбудованих мов. На відміну, наприклад, від Python в ChaiScript немає власних коштів для запуску потоків, але кожен потік батьківської програми може вільно викликати будь-які команди інтерпретатора, не побоюючись накладок і не роблячи ніяких спеціальних дій для захисту даних в скрипті.




Однією з потенційно корисних можливостей ChaiScript є динамічно завантажувані модулі. Саме для них при компонуванні в Linux необхідна бібліотека ldl. В скрипті можна під час виконання завантажувати спеціальним чином створені динамічні бібліотеки, використовуючи функцію load_module ( "ім`я модуля").

Модуль в ChaiScript - це лише винесений в динамічну бібліотеку набір функцій-він не створює новий простір імен як в уже згаданому Python. Щоб створити найпростіший модуль, потрібно написати приблизно такий код:
#include #include #include
void hello_module () {
std :: cout lt; lt; "Hello from my_module!" lt; lt; std :: endl;
}
CHAISCRIPT_MODULE_EXPORT chaiscript :: ModulePtr create_chaiscript_module_my_module ()
{
chaiscript :: ModulePtr m (new chaiscript :: Module ()) -
m-gt; add (chaiscript :: fun (hello_module), "hello_module") -
return m;
}

Все досить інтуїтивно зрозуміло: модуль експортує одну функцію hello_module, а макрос CHAISCRIPT_MODULE_EXPORT відповідає за всю внутрішню «бухгалтерію». Однак домогтися того, щоб скомпільований модуль завантажувався в інтерпретатор, виявилося не так-то простою справою. Методом проб і помилок вдалося з`ясувати два критичних моменти.

По-перше, в рядку:
create_chaiscript_module_my_module ()

обов`язковим префіксом є «create_chaiscript_module_», а весь наступний - це власне ім`я модуля.

По-друге, ім`я одержуваної бібліотеки повинно бути lib.so (в нашому випадку libmy_module.so). У мене в 64-бітної Ubunu 11.10 успішною виявилася компіляція з такими прапорами:
$ G ++ -fPIC -Кпуть до ChaiScriptgt; -o my_module.o -c my_module.cpp
$ G ++ -fPIC -shared -o libmy_module.so -ldl my_module.o

Перевірити модуль можна так:
$ ./chai -c `load_module ( "my_module") - hello_module ()`

На екрані з`явиться «Hello from my_module!». Модулі дозволяють розбити програму на незалежні компоненти, які можна при необхідності завантажувати прямо з скриптів, не втрачаючи при цьому в швидкості.

висновки

ChaiScript, безумовно, мова не для всіх. Хоча б тому, що він не є самодостатнім, як Python або Ruby. Ідейно він найбільше нагадує браузерні javascript, який не потрібний у відриві від самого браузера (Втім, активне поширення Node.js прагне виправити цю ситуацію. - Прим. Ред.), Але в той же час робить браузери надзвичайно потужними інструментами. ChaiScript намертво прив`язаний до С ++, і в цьому його основна сила. Вбудовування повноцінного інтерпретатора в будь-яку програму на С ++ займає кілька хвилин (в найпростіших випадках) і навіть не вимагає ніякої додаткової компонування зі сторонніми бібліотеками.

Сама ідея мови, який повністю покладається на типи даних батьківської програми, здається мені по-справжньому революційною. Сумнозвісний бич всіх скриптових мов - перетворення даних між компільовані бекендом і скриптовою фронтен-будинок. У ChaiScript просто нічого перетворювати: все, що треба скрипту, оголошується на С ++ і реєструється в інтерпретаторі.

Є у ChaiScript і недоліки. Мова дуже простий, в ньому немає повноцінних класів, просторів імен, замикань, виразної стандартної бібліотеки. Документація, м`яко кажучи, неповна і організована не найкращим чином. Проте, ChaiScript може бути ідеальним варіантом для проектів на С ++, де потрібно «малою кров`ю» реалізувати скриптова мова і немає потреби в самодостатніх мовах, таких як Python або Lua.


ІНШЕ

Qt 5: зміни в c ++ api і модулях фото

Qt 5: зміни в c ++ api і модулях

Відео: Qt5 C ++ - QTimer Взагалі склалося враження, що розробники Qt 5 доклали багато зусиль, щоб програмісти С ++…

Seed7: бібліотеки фото

Seed7: бібліотеки

Відео: пентагональними призма з насіння льону. П`ятикутна призма. геометричні фігури.Стереометрія Якщо Сі або C ++ без…

Qtiplot: аналіз даних фото

Qtiplot: аналіз даних

Відео: Qtiplot Intro 2 scatter plot, linear regression, error bars, reading data from graphs Можна сміливо сказати, що…

Ultimate ++: схеми баз даних фото

Ultimate ++: схеми баз даних

Відео: Бази даних, лекція №1 (2013) Об`єкти SqlExp кардинально полегшують створення запитів, але створення самих…

» » Взаємодія chaiscript з c ++: контейнери, модулі і багатопоточність