ports
erlang的port方式做跨语言调用会启动一个外部的操作系统进程,
就像后端和前端交互一样与这个进程交互
erl_interface
官方自带的例子有点问题,得加上-lpthread才能编译通过,如下1
2gcc -o extprg -I/usr/local/lib/erlang/lib/erl_interface-3.7.6/include/ -L/usr/local/lib/erlang/lib/erl_interface-3.7.6/lib/ \
complex.c erl_comm.c ei.c -lerl_interface -lei -lpthread
测试1
2> complex2:start("extprg").
这里根据搜索路径可能需要改成complex2:start("./extprg").
port driver
erlang的port driver官方自带的例子有问题1
2官方: gcc -o exampledrv -fpic -shared complex.c port_driver.c
正确的应该是: gcc -o example_drv.so -fpic -shared complex.c port_driver.c -I /usr/local/lib/erlang/usr/include/
c_node
c node结点名的规则
If short node names are used, the plain name of the node will be cN where N is an integer.
If long node names are used, there is no such restriction.
An example of a C node name using short node names is thus c1@idril, an example using long node names is [email protected].
遇到的问题1
2
3
4
5cnode_s.c: In function ‘my_listen’:
cnode_s.c:87:5: warning: incompatible implicit declaration of built-in function ‘memset’ [enabled by default]
memset((void*) &addr, 0, (size_t) sizeof(addr));
^
/usr/bin/ld: cannot find -lsocket
解决过程:
去掉了-lsocket
编译短名称的cserver1
gcc -o cserver -I /usr/local/lib/erlang/lib/erl_interface-3.7.6/include/ -L /usr/local/lib/erlang/lib/erl_interface-3.7.6/lib/ complex.c cnode_s.c -l erl_interface -l ei -l nsl -l pthread
编译长名称的cserver21
gcc -o cserver2 -I /usr/local/lib/erlang/lib/erl_interface-3.7.6/include/ -L /usr/local/lib/erlang/lib/erl_interface-3.7.6/lib/ complex.c cnode_s2.c -l erl_interface -l ei -l nsl -l pthread
编译cclient1
gcc -o cclient -I /usr/local/lib/erlang/lib/erl_interface-3.7.6/include/ -L /usr/local/lib/erlang/lib/erl_interface-3.7.6/lib/ complex.c cnode_c.c -l erl_interface -l ei -l nsl -l pthread
使用短名称的示例:1
2
3
4
5
6
7
8
9
10
11
12$ ./cserver 3459
Connected to e1 -desktop
$ erl -sname e1 -setcookie secretcookie
Erlang R15B (erts-5.9) [source] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
(e11> -desktop)
(e11> complex3:foo(3). -desktop)
4
(e12> complex3:bar(3). -desktop)
6
使用长名称的示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$ ./cserver2 3459
Connected to e1@192.168
$ erl -name e1@192.168 -setcookie secretcookie
Erlang R15B (erts-5.9) [source] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5 (abort with ^G)
(e1@192.168 )1> complex4:bar(2).
4
(e1@192.168 )2> complex4:bar(2).
4
(e1@192.168 )3> complex4:foo(3).
4
(e1@192.168 )4> complex4:foo(30).
31
使用cclient的示例1
2
3
4
5
6
7
8
9
10
11
12
13$ ./cclient
Connected to ei -desktop
$ erl -sname e1 -setcookie secretcookie
Erlang R15B (erts-5.9) [source] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
(e11> complex3:foo(3). -desktop)
4
(e12> complex3:foo(4). -desktop)
5
(e13> complex3:bar(4). -desktop)
8
NIF
NIFs are most suitable for synchronous functions like foo and bar in the example,
that does some relatively short calculations without side effects and return the result
适用于相对简单且无副作用的同步函数调用
a crash in a NIF will bring the emulator down
We use the directive on_load to get function init to be automatically called when the module is loaded.
If init returns anything other than ok, such when the loading of the NIF library fails in this example,
the module will be unloaded and calls to functions within it will fail.
Loading the NIF library will override the stub implementations and cause calls to foo and bar to be dispatched to the NIF implementations instead.
编译1
$ gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c -I /usr/local/lib/erlang/usr/include/
测试1
2
3
4
5
6
7
8
9
10
11
12
13
14$ erl
Erlang R15B (erts-5.9) [source] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
c(complex6).
{ok,complex6}
100). complex6:foo(
101
1000000000000). complex6:foo(
** exception error: bad argument
in function complex6:foo/1
called as complex6:foo(1000000000000)
3000). complex6:bar(
6000