The mapping of OMG IDL to the Erlang programming language when Erlang
generic server is the back-end of choice is similar to the one used in
the chapter 'OMG IDL Mapping'.
The only difference is on the generated code, a client stub and
server skeleton
to an Erlang gen_server
.
In the Erlang shell type :
ic:gen(<filename>, [{be, erl_genserv}])
.
For each IDL interface <interface name>
defined in the IDL file :
_impl
.
For each function defined in the IDL interface :
In this example, a file "random.idl" generates code for the plain erlang back-end :
module rmod { interface random { double produce(); oneway void init(in long seed1, in long seed2, in long seed3); }; };
Compile the file :
Erlang BEAM) emulator version 4.9 Eshell V4.9 (abort with ^G) 1> ic:gen(random,[{be, erl_genserv}]). Erlang IDL compiler version 2.5.1 ok 2>
When the file "random.idl" is compiled it produces five files: two for
the top scope, two for the interface scope, and one for the module
scope. The header files for top scope and interface
are empty and not shown here. In this case, only the file for the interface
rmod_random.erl
is important :.
-module(rmod_random). %% Interface functions -export([produce/1, init/4]). %% Type identification function -export([typeID/0]). %% Used to start server -export([oe_create/0, oe_create_link/0, oe_create/1]). -export([oe_create_link/1, oe_create/2, oe_create_link/2]). -export([start/2, start_link/3]). %% gen server export stuff -behaviour(gen_server). -export([init/1, terminate/2, handle_call/3]). -export([handle_cast/2, handle_info/2]). %%------------------------------------------------------------ %% %% Object interface functions. %% %%------------------------------------------------------------ %%%% Operation: produce %% %% Returns: RetVal %% produce(OE_THIS) -> gen_server:call(OE_THIS, produce, infinity). %%%% Operation: init %% %% Returns: RetVal %% init(OE_THIS, Seed1, Seed2, Seed3) -> gen_server:cast(OE_THIS, {init, Seed1, Seed2, Seed3}). %%------------------------------------------------------------ %% %% Server implementation. %% %%------------------------------------------------------------ %%------------------------------------------------------------ %% %% Function for fetching the interface type ID. %% %%------------------------------------------------------------ typeID() -> "IDL:rmod/random:1.0". %%------------------------------------------------------------ %% %% Server creation functions. %% %%------------------------------------------------------------ oe_create() -> start([], []). oe_create_link() -> start_link([], []). oe_create(Env) -> start(Env, []). oe_create_link(Env) -> start_link(Env, []). oe_create(Env, RegName) -> start(RegName, Env, []). oe_create_link(Env, RegName) -> start_link(RegName, Env, []). %%------------------------------------------------------------ %% %% Start functions. %% %%------------------------------------------------------------ start(Env, Opt) -> gen_server:start(?MODULE, Env, Opt). start_link(Env, Opt) -> gen_server:start_link(?MODULE, Env, Opt). start(RegName, Env, Opt) -> gen_server:start(RegName, ?MODULE, Env, Opt). start_link(RegName, Env, Opt) -> gen_server:start_link(RegName, ?MODULE, Env, Opt). init(Env) -> %% Call to implementation init rmod_random_impl:init(Env). terminate(Reason, State) -> rmod_random_impl:terminate(Reason, State). %%%% Operation: produce %% %% Returns: RetVal %% handle_call(produce, OE_From, OE_State) -> rmod_random_impl:produce(OE_State); %%%% Standard Operation: oe_get_interface %% handle_call({OE_THIS, oe_get_interface, []}, From, State) -> {reply, [{"produce",{tk_double,[],[]}}, {"init",{tk_void,[tk_long,tk_long,tk_long],[]}}], State}; %%%% Standard gen_server call handle %% handle_call(stop, From, State) -> {stop, normal, ok, State}. %%%% Operation: init %% %% Returns: RetVal %% handle_cast({init, Seed1, Seed2, Seed3}, OE_State) -> rmod_random_impl:init(OE_State, Seed1, Seed2, Seed3); %%%% Standard gen_server cast handle %% handle_cast(stop, State) -> {stop, normal, State}. %%%% Standard gen_server handles %% handle_info(X, State) -> {noreply, State}.
The implementation file should be called rmod_random_impl.erl
and could look like this :
-module('rmod_random_impl'). -export([init/1, terminate/2]). -export([produce/1,init/4]). init(Env) -> {ok, []}. terminate(From, Reason) -> ok. produce(_Random) -> case catch random:uniform() of {'EXIT',_} -> true; RUnif -> {reply,RUnif,[]} end. init(_Random,S1,S2,S3) -> case catch random:seed(S1,S2,S3) of {'EXIT',_} -> true; _ -> {noreply,[]} end.
Compiling the code :
2> make:all(). Recompile: rmod_random Recompile: oe_random Recompile: rmod_random_impl up_to_date
Running the example :
3> {ok,R} = rmod_random:oe_create(). {ok,<0.30.0> 4> rmod_random:init(R,1,2,3). ok 5> rmod_random:produce(R). 1.97963e-4 6>