相关文档http://www.erlang.org/doc/tutorial/erl_interface.html
http://www.erlang.org/doc/apps/erl_interface/ei_users_guide.html
(1),字符串被截断问题
片段说明:
输入[1,2,0,0,2,3]
149行会返回[1,2,0,0.2,3]
150行会返回[1,2] 0认为是结束符号,所以截断了
----
149 intp = erl_mk_estring(estring,i);
150 //intp = erl_mk_string(estring);
ETERM * erl_mk_estring(string, len)
Types:
This function creates a list from a sequence of bytes.
string is a buffer containing a sequence of bytes. The buffer does not need to be zero-terminated.
len is the length of string.
The function returns an Erlang list object corresponding to the character sequence in string.
(2)、 tuplep = erl_decode(buf);
(3)、关于ETERM 及部分类型
char *fname=(fnp)->uval.aval.a; 等价于char *fname=ERL_ATOM_PTR(fnp).此处只是一个宏定义
ETERM数据类型是一个结构体,内容又是一个联合体,联合体里面又是结构体...
如果是整型则用ERL_INT_VALUE(fnp);
(4)、采用erl_hd/1|erl_tl/1 或 ERL_CONS_HEAD/1|ERL_CONS_TAIL/1遍历list
60 ETERM *headH;
61 int headHInt;
62 while(erl_length(argp2)){
63 headH = erl_hd(argp2);
64 argp2 = erl_tl(argp2);
65 headHInt= ERL_INT_VALUE(headH);
66 fprintf(stderr, "headHInt=%i\n\r", headHInt);
67 estring[i]=headHInt;
68 fprintf(stderr, "headHInt=%c\n\r", headHInt);
69 i++;
70 }
(5)如果是字符串可以用erl_iolist_to_string
binary 用 erl_iolist_to_binary(term)
学习过程测试代码
- 1 /* ei.c */
- 2 #include "erl_interface.h"
- 3 #include "ei.h"
- 4 #include "stdio.h"
- 5 typedef unsigned char byte;
- 6 int main() {
- 7 ETERM *tuplep, *intp;
- 8 ETERM *fnp, *argp, *argp1, *argp2;
- 9 ETERM testt;
- 10 int res;
- 11 byte buf[100];
- 12 long allocated, freed;
- 13 erl_init(NULL, 0);
- 14 while (read_cmd(buf) > 0) {
- 15 tuplep = erl_decode(buf);
- 16 fnp = erl_element(1, tuplep);
- 17 argp = erl_element(2, tuplep);
- 18 int tuplesize=ERL_TUPLE_SIZE(tuplep);
- 19 fprintf(stderr, "tuplesize=%i\n\r", tuplesize);
- 20 if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
- 21 res = foo(ERL_INT_VALUE(argp));
- 22 } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 17) == 0) {
- 23 int a = ((argp)->uval.ival.i);
- 24 //a = ((argp)->uval.llval.i);
- 25 char *fname=(fnp)->uval.aval.a;
- 26 //a = testt.uval.ival.i;
- 27 char *arg2;
- 28 if(tuplesize==3){
- 29 argp1 = erl_element(3, tuplep);
- 30 arg2=ERL_ATOM_PTR(argp1);
- 31 fprintf(stderr, "A = %i,arg2=%s\n\r",a,arg2);
- 32 }else if(tuplesize=4){
- 33 char *arg3;
- 34 argp2 = erl_element(4, tuplep);
- 35 arg3=ERL_ATOM_PTR(argp2);
- 36 int atomsize=ERL_ATOM_SIZE(argp2);
- 37 int ioListSize = erl_iolist_length(argp2);
- 38 int listSize = erl_length(argp2);
- 39 fprintf(stderr, "\n\rioListSize=%i\n\r", ioListSize);
- 40 fprintf(stderr, "\n\rlistSize=%i\n\r", listSize);
- 41 int isAtom = ERL_IS_ATOM(argp2);
- 42 int isList = ERL_IS_LIST(argp2);
- 43 int isBinary = ERL_IS_BINARY(argp2);
- 44 ETERM *ioListBin = erl_iolist_to_binary(argp2);
- 45 char *ioListString = erl_iolist_to_string(argp2);
- 46 fprintf(stderr, "\n\rioListBin=");
- 47 erl_print_term(stderr, ioListBin);
- 48 fprintf(stderr, "\n\riargp2=");
- 49 erl_print_term(stderr, argp2);
- 50 fprintf(stderr, "\n\rioListString=%s\n\r",ioListString);
- 51 fprintf(stderr, "A = %i,arg3=%s,atomsize=%i,isAtom=%i,isList=%i,isBinary=%i\n\r",
- 52 a,arg3,atomsize,isAtom,isList,isBinary);
- 53 ETERM *listhss = erl_hd(argp2);
- 54 int lh = ERL_INT_VALUE(listhss);
- 55 fprintf(stderr, "lh=%i\n\r",lh);
- 56
- 57 ETERM *headH;
- 58 while(erl_length(argp2)){
- 59 headH = erl_hd(argp2);
- 60 argp2 = erl_tl(argp2);
- 61 int headHInt = ERL_INT_VALUE(headH);
- 62 fprintf(stderr, "headHInt=%i\n\r", headHInt);
- 63 fprintf(stderr, "headHInt=%c\n\r", headHInt);
- 64 }
- 65
- 66 fprintf(stderr, "\n\r");
- 67 fprintf(stderr, "\n\r");
- 68
- 69
- 70
- 71 // operator
- 72 int erl_siz;
- 73 erl_siz=erl_size(tuplep);
- 74 ETERM *list = erl_mk_empty_list();
- 75 ETERM *anAtom,*anInt;
- 76 anAtom = erl_mk_atom("langxw");
- 77 anInt = erl_mk_int(26);
- 78 list = erl_cons(anAtom, list);
- 79 list = erl_cons(anInt, list);
- 80 list = erl_cons(anAtom, list);
- 81 int listsize = erl_length(list);
- 82 ETERM *listh = erl_hd(list);
- 83 ETERM *listt = erl_tl(list);
- 84 ETERM *listh1 = ERL_CONS_HEAD(list);
- 85 ETERM *listt1 = ERL_CONS_TAIL(list);
- 86 int listhint = ERL_INT_VALUE(listh);
- 87 int listhint1 = ERL_INT_VALUE(listh1);
- 88 fprintf(stderr, "erl_size=%i,listsize=%i,listhint=%i\n\r", erl_siz,listsize,listhint);
- 89 erl_print_term(stderr,listt);
- 90 fprintf(stderr, "erl_size=%i,listsize=%i,listhint1=%i\n\r", erl_siz,listsize,listhint1);
- 91 erl_print_term(stderr,listt1);
- 92 erl_free_compound(list);
- 93
- 94 }
- 95
- 96 fprintf(stderr, "A = %i,fname=%s\n\r",a,fname);
- 97 res = bar(ERL_INT_VALUE(argp));
- 98 }
- 99 /**
- 100 ETERM *ep;
- 101 ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
- 102 "madonna",
- 103 21,
- 104 erl_format("[{adr,~s,~i}]","E-street",42));
- 105 fprintf(stderr, "s=%i\n\r",);
- 106 */
- 107 ETERM *pattern1,*pattern,*term, *ep;
- 108 pattern = erl_format("{Name,Age,Age}");
- 109 pattern1 = erl_format("Pa");
- 110 term = erl_format("{madonna,21,21}");
- 111 if(erl_match(pattern1, term)){
- 112 ep = erl_var_content(pattern, "Age");
- 112 ep = erl_var_content(pattern, "Age");
- 113 //int a = ((ep)->uval.ival.i;
- 114 //*ep.uval.tval;
- 115 //fprintf(stderr, "A = %i\n\r",a);
- 116 fprintf(stderr, "Pa = ");
- 117 erl_print_term(stderr, ep);
- 118 }
- 119 /**
- 120 if (erl_match(pattern, term)) {
- 121 fprintf(stderr, "Yes, they matched: Age = ");
- 122 ep = erl_var_content(pattern, "Age");
- 123 fprintf(stderr, "Yes, they matched: Name = ");
- 124 erl_print_term(stderr, ep);
- 125 ep = erl_var_content(pattern, "Name");
- 126 erl_print_term(stderr, ep);
- 127 fprintf(stderr,"\n\r");
- 128 erl_free_term(ep);
- 129 }
- 130 */
- 131 erl_free_term(pattern);
- 132 erl_free_term(term);
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141 intp = erl_mk_int(res);
- 142 erl_encode(intp, buf);
- 143 write_cmd(buf, erl_term_len(intp));
- 144 erl_free_compound(tuplep);
- 145 erl_free_term(fnp);
- 146 erl_free_term(argp);
- 147 erl_free_term(intp);
- 148 }
- 149 }
- 1 -module(complex2).
- 2 -export([start/1, stop/0, init/1]).
- 3 -export([foo/1,
- 4 bar/2,
- 5 bar/3,
- 6 bar/1]).
- 7 start(ExtPrg) ->
- 8 spawn(?MODULE, init, [ExtPrg]).
- 9 stop() ->
- 10 complex ! stop.
- 11 foo(X) ->
- 12 call_port({foo, X}).
- 13 bar(Y) ->
- 14 call_port({bar, Y}).
- 15 bar(Y,X) ->
- 16 call_port({bar, Y, X}).
- 17 bar(Y,X,Z) ->
- 18 call_port({bar, Y, X, Z}).
- 19 call_port(Msg) ->
- 20 complex ! {call, self(), Msg},
- 21 receive
- 22 {complex, Result} ->
- 23 Result
- 24 end.
- 25 init(ExtPrg) ->
- 26 register(complex, self()),
- 27 process_flag(trap_exit, true),
- 28 Port = open_port({spawn, ExtPrg}, [{packet, 2}, binary]),
- 29 loop(Port).
- 30 loop(Port) ->
- 31 receive
- 32 {call, Caller, Msg} ->
- 33 Port ! {self(), {command, term_to_binary(Msg)}},
- 34 receive
- 35 {Port, {data, Data}} ->
- 36 Caller ! {complex, binary_to_term(Data)}
- 37 end,
- 38 loop(Port);
- 39 stop ->
- 40 Port ! {self(), close},
- 41 receive
- 42 {Port, closed} ->
- 43 exit(normal)
- 44 end;
- 45 {'EXIT', Port, Reason} ->
- 46 exit(port_terminated)
- 47 end.
///complex.c
- 1 int foo(int x)
- 2 {
- 3 return x+1;
- 4 }
- 5 int bar(int x)
- 6 {
- 7 return x*2;
- 8 }
- retun.........
- 147 //intp = erl_mk_int(res);
- 148 //intp = erl_mk_string("ssss");
- 149 intp = erl_mk_estring(estring,i);
- 150 //intp = erl_mk_string(estring);
- 151
- 152 erl_encode(intp, buf);
- 153 write_cmd(buf, erl_term_len(intp));
- 154 erl_free_compound(tuplep);
- 155 erl_free_term(fnp);
- 156 erl_free_term(argp);
- 157 erl_free_term(intp);
- 158 }
- 159 }