C++ meets JS
Italian C++ MeetUp
24 October 2015, Rome
- twitter.com/glmeocci
- glmeocci@gmail.com
Me!
-
C++11/14 addicted
-
Js & web developer
-
#FP student (Scala, Elixir, Haskell)
I come from Florence!
I'm working in CommProve as
SW Engineer (BigData team)
- Easy to integrate in any C++ application
- Simple to teach (especially for non-programmers)
- Very powerfull & productive programming language
- There are a lot of well written/documented js libraries
- ...
Why JavaScript?
- Efficent (and quite easy) integration with C++11
- Fast Property Access
- Dynamic Machine Code Generation
- Efficient Garbage Collection
- OpenSource and wide adopted (Node.js for example)
Why Google V8?
Download the source code:
- https://chromium.googlesource.com/v8/v8/+/master/docs/using_git.md
Compile:
- https://chromium.googlesource.com/v8/v8/+/master/docs/building_with_gyp.md
- Copy include & libs (look into out folder) where you want
download & make
Rome V8 project
- C++11
- V8
- ZeroMQ
Not production ready
Not tested!
Not completed!
Not documented :(
But quite easy to understand
Client
var socket = new zsocket("127.0.0.1", 9090);
socket.connect();
for (var i = 0; i < 10; i++)
{
socket.send("test " + i);
var reply = socket.recv();
println(reply);
}
Server
var socket = new zsocket("*", 9090);
socket.bind();
for (var i = 0; i < 10; i++)
{
var msg = socket.recv();
println("Received: " + msg);
socket.send("R: " + msg);
}
V8 Handles & Scope
rv8.h anatomy
RV8
RV8() construct & initialize
add_global_function(string, fun)
execute()
~RV8() release resources
RVObject
RVObject() constructor
add_function(string, fun)
invoke_jsfun(fname, ...)
adding global function
int main(int argc, char* argv[])
{
RV8 rv8_engine;
//add println function
rv8_engine.add_global_function("println", [](js_callinfo_t args){
HandleScope handle_scope(args.GetIsolate());
bool first = true;
for (int i = 0; i < args.Length(); i++)
{
if (first)
first = false;
else
cout << " ";
pretty_print(*args[i]);
}
cout << endl;
});
...
// execute the script
rv8_engine.execute(script_fname);
}
using js_callinfo_t = const v8::FunctionCallbackInfo<v8::Value>&;
adding object function
class ZSocketTempl final : public RVObject<ZSocket>
{
public:
ZSocketTempl(RV8& rv8_engine);
~ZSocketTempl() {
for (auto e : v_zsocket) delete e;
}
private:
RV8& engine;
std::vector<ZSocket*> v_zsocket;
};
ZSocketTempl::ZSocketTempl(RV8& rv8_engine)
: RVObject<ZSocket>{rv8_engine}, engine{rv8_engine}
{
engine.add_global_function("zsocket", [this](js_callinfo_t args){
// add object function here
add_function("connect", [](js_callinfo_t args, ZSocket* obj){
stringstream ip_connect;
ip_connect << "tcp://" << obj->ip << ":" << obj->port;
cerr << "connect: " << ip_connect.str() << endl;
obj->socket = new zmq::socket_t{zmq_context, ZMQ_REQ};
obj->socket->connect(ip_connect.str());
}, c_obj);
});
}
calling js from C++
rv8_engine.invoke_jsfun("exit_callback", "bye bye", 42);
template <typename ...Args>
bool invoke_jsfun(const std::string& function_name, Args ...args)
{
HandleScope handle_scope(engine_isolate);
Local<String> jf_name = rv::string(engine_isolate, function_name);
Local<Value> jsfun;
Local<Context> _context = Local<Context>::New(engine_isolate, context);
if (
!_context->Global()->Get(_context, jf_name).ToLocal(&jsfun)
||
!jsfun->IsFunction()
) { return false; }
const size_t args_len = sizeof...(args);
Handle<Value> arr[args_len];
Local<Function> fun = Local<Function>::Cast(jsfun);
fill_parameter(arr, 0, std::forward<Args>(args)...);
fun->Call(_context, _context->Global(), args_len, arr);
return true;
}
Questions?
C++ meets Javascript
By Gian Lorenzo Meocci
C++ meets Javascript
Italian C++ MeetUp Rome
- 1,075