-
Notifications
You must be signed in to change notification settings - Fork 0
Erlang C++ Interface
License
LGPL-2.1, Unknown licenses found
Licenses found
LGPL-2.1
LICENSE
Unknown
license.sh
coretech/eixx
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
eixx - Erlang C++ Interface Library
===================================
This library provides a set of classes for convenient marshaling
of Erlang terms between processes as well as connecting to other
distributed Erlang nodes from a C++ application.
The marshaling classes are built on top of ei library included in
{@link http://www.erlang.org/doc/apps/erl_interface erl_interface}.
It is largely inspired by the {@link http://code.google.com/p/epi epi}
project, but is a complete rewrite with many new features and
optimization enhancements.
This library adds on the following features:
- Use of reference-counted smart pointers for complex terms and
by-value copied simple terms (e.i. integers, doubles, bool, atoms).
- Ability to provide custom memory allocators.
- Encoding/decoding of nested terms using a single function call
(eterm::encode() and eterm::eterm() constructor).
- Global atom table for fast manipulation of atoms.
The library consists of two separate parts:
- Term marshaling (included by marshal.hpp or eixx.hpp)
- Distributed node connectivity (included by connect.hpp or eixx.hpp)
The connectivity library implements a richer set of features than
what's available in erl_interface - it fully supports process
linking and monitoring. The library is fully asynchronous and allows
handling many connections and mailboxes in one OS thread.
Ths library is dependend on {@link http://www.boost.org BOOST}
project and erl_interface, which is a part of the
{@link www.erlang.org Erlang} distribution.
Downloading
===========
Repository location: http://github.com/saleyn/eixx
$ git clone git@github.com:saleyn/eixx.git
Building
========
Make sure that you have autoconf-archive package installed:
http://www.gnu.org/software/autoconf-archive
Run:
$ ./bootstrap
$ ./configure --with-boost="/path/to/boost" [--with-erlang="/path/to/erlang"] \
[--prefix="/target/install/path"]
$ make
$ make install # Default install path is ./install
Author
======
Serge Aleynikov <saleyn at gmail dot com>
LICENSE
=======
GNU Lesser General Public License
Example
=======
Here's an example use of the eixx library:
void on_message(otp_mailbox& a_mbox, boost::system::error_code& ec) {
// On timeout ec == boost::asio::error::timeout
if (ec == boost::asio::error::timeout) {
std::cout << "Mailbox " << a_mbox.self() << " timeout: "
<< ec.message() << std::endl;
} else {
// The mailbox has a queue of transport messages.
// Dequeue next message from the mailbox.
boost::scoped_ptr<transport_msg> dist_msg;
while (dist_msg.reset(a_mbox.receive())) {
std::cout << "Main mailbox got a distributed transport message:\n "
<< *p << std::endl;
// Use the following pattern for a pattern match on the message.
static const eterm s_pattern = eterm::format("{From, {command, Cmd}}");
varbind binding;
if (s_pattern.match(dist_msg->msg(), &binding)) {
const eterm* cmd = binding->find("Cmd");
std::cout << "Got a command " << *cmd << std::endl;
// Process command, e.g.:
// process_command(binding["From"]->to_pid(), *cmd);
}
}
}
// Schedule next async receive of a message (can also provide a timeout).
a_mbox.async_receive(&on_message);
}
void on_connect(otp_connection* a_con, const std::string& a_error) {
if (!a_error.empty()) {
std::cout << a_error << std::endl;
return;
}
// Illustrate creation of Erlang terms.
eterm t1 = eterm::format("{ok, ~i}", 10);
eterm t2 = tuple::make(10, 1.0, atom("test"), "abc");
eterm t3("This is a string");
eterm t4(tuple::make(t1, t2, t3));
otp_node* node = a_con->node();
otp_mailbox* mbox = node->get_mailbox("main");
// Send a message: {{ok, 10}, {10, 1.0, 'test', "abc"}, "This is a string"}
// to an Erlang process named 'test' running
// on node "abc@myhost"
node->send(mbox.self(), a_con->remote_node(), atom("test"), t4);
}
int main() {
use namespace eixx;
otp_node node("abc");
otp_mailbox* mbox = node.create_mailbox("main");
node.connect(&on_connect, "abc@myhost");
// Asynchronously receive a message with a deadline of 10s:
mbox->async_receive(&on_message, 10000);
node.run();
}
Testing distributed transport
=============================
$ make
Run tests:
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./test_eterm
Test distributed transport:
$ cd src
# In this example we assume the host name of "fc12".
[Shell A]$ erl -sname abc
(abc@fc12)1> register(test, self()).
[Shell B]$ ./test_node -n a@fc12 -r abc@fc12
Connected to node: abc@fc12
I/O server got a message:
#DistMsg{
type=SEND,
cntrl={2,'',#Pid<a@fc12.1.0>},
msg={io_request,#Pid<abc@fc12.273.0>,#Pid<a@fc12.1.0>,
{put_chars,<<"This is a test string">>}}}
The message above is a result of the on_connect() handler in test_node.cpp
issuing an rpc call to the abc@fc12 node of `io:put_chars("This is a test
string")'. This the call selects a locally registered process called
'io_server' as the group leader for this rpc call, the I/O output is sent
to that mailbox.
Now you can try to send a message from Erlang to the 'main' mailbox
registered on the C++ node:
[Shell A]
(abc@fc12)2> {main, a@fc12} ! "This is a test!".
[Shell B]
Main mailbox got a message:
#DistMsg{
type=REG_SEND,
cntrl={6,#Pid<abc@fc12.46.0>,'',main},
msg="This is a test!"}
About
Erlang C++ Interface
Topics
Resources
License
LGPL-2.1, Unknown licenses found
Licenses found
LGPL-2.1
LICENSE
Unknown
license.sh
Stars
Watchers
Forks
Packages 0
No packages published
Languages
- C++ 95.8%
- M4 1.6%
- C 1.5%
- Makefile 1.1%