How do I connect Erlang to C++?

1.2k views Asked by At

I have written a very simple C++ piece of code:

#include <iostream>
using namespace std;

int main() {

int message;

cin >> message;
cout << message;
return 0;
}

I have tested it in the shell - it returns a value which was input in the shell.

But when I try to call it from Erlang, it returns {exit_status,0}, which as I understand means that it just exited.

The Erlang code is here:

p(Param) ->
    ?DBG("Starting~n", []),
    Cmd = "./Echo\n",
    Port = open_port({spawn,Cmd}, [binary,{packet, 4},  exit_status]),
    Payload = term_to_binary(list_to_binary(integer_to_list(Param))),
    ?DBG("Opened the port: ~w~n", [Port]),
    erlang:port_command(Port, Payload),
    ?DBG("Sent command to port: ~w~n", [Payload]),
    ?DBG("Ready to receive results for command: ~w~n", [Payload]),
    receive
        {Port, {data, Data}} ->
            ?DBG("Received data: ~w~n", [Data]),
            {result, Text} = binary_to_term(Data),
            Blah = binary_to_list(Text),
            io:format("~p~n", [Blah]);
        Other ->
            io:format("Unexpected data: ~p~n", [Other])

    end.

How do I connect my Erlang port to this simple C++ code?

UPD:

Changed the C++ code to this (Useless' version):

#include <iostream>
using namespace std;

int main() {

int message;

cin.read(reinterpret_cast<char *>(&message), 4);
cout.write(reinterpret_cast<char *>(&message), 4);
return 0;
}

Erlang port process still gets {exit_value,0}. If I run this code in the shell, the keyboard input is not echoed until I press Return twice.

3

There are 3 answers

0
Prof. Falken On

Maybe an acceptable workaround could be IPC? ZeroC has excellent C++ support and it would seem, decent Erlang support too.

3
Useless On

You know that the extraction operator cin >> expects formatted input, right? Which is to say, it would extract a string representing an integer, but probably won't deal well with a 4-byte binary integer or whatever that Erlang is sending.

If you want to read binary data, use

cin.read(reinterpret_cast<char *>(&message), 4);
cout.write(reinterpret_cast<char *>(&message), 4);

for example. Or, of course, write and receive text on the Erlang side.

0
kuenishi On

With {packet, 4} Erlang adds and expects additional information for the following binaries. And, term_to_binary/1 encodes integer into BERT format (kind of a binary format like thrift). For an easy test you should use text protocol with parsing:

not: Payload = term_to_binary(list_to_binary(integer_to_list(Param))),

but: Payload = <<"hello, C++">>,