rebar3 cmake 项目学习
erlang 与c 的通信方式,包含了port 以及nif,以下是使用nif 的测试
创建项目
一个lib 一个cmake
- 命令
rebar3 new lib myapp
cd myapp
rebar3 new cmake
项目结构
├── LICENSE.md
├── README.md
├── c_src
│ ├── Makefile
│ └── app.c
├── rebar.config
├── rebar.lock
└── src
├── myapp.app.src
└── myapp.erl
- nif 代码模块
c_src/app.c
#include "erl_nif.h"
static ERL_NIF_TERM
mk_atom(ErlNifEnv* env, const char* atom)
{
ERL_NIF_TERM ret;
if(!enif_make_existing_atom(env, atom, &ret, ERL_NIF_LATIN1))
{
return enif_make_atom(env, atom);
}
return ret;
}
static ERL_NIF_TERM
mk_error(ErlNifEnv* env, const char* mesg)
{
return enif_make_tuple2(env, mk_atom(env, "error"), mk_atom(env, mesg));
}
static ERL_NIF_TERM
repeat(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifEnv* msg_env;
ErlNifPid pid;
ERL_NIF_TERM copy;
if(argc != 2)
{
return enif_make_badarg(env);
}
if(!enif_is_pid(env, argv[0]))
{
return mk_error(env, "not_a_pid");
}
if(!enif_get_local_pid(env, argv[0], &pid))
{
return mk_error(env, "not_a_local_pid");
}
msg_env = enif_alloc_env();
if(msg_env == NULL)
{
return mk_error(env, "environ_alloc_error");
}
copy = enif_make_copy(msg_env, argv[1]);
if(!enif_send(env, &pid, msg_env, copy))
{
enif_free(msg_env);
return mk_error(env, "error_sending_term");
}
enif_free_env(msg_env);
return mk_atom(env, "ok");
}
static ErlNifFunc nif_funcs[] = {
{"repeat", 2, repeat}
};
ERL_NIF_INIT(myapp, nif_funcs, NULL, NULL, NULL, NULL);
代码上比较类似node 的napi 模块开发,与不少框架开发模式类似
src/myapp.erl 主要是调用c模块
-module(myapp).
-export([repeat/2]).
-on_load(init/0). # 加载的时候加载c 模块
-define(APPNAME, myapp).
-define(LIBNAME, myapp).
init()->
SoName = case code:priv_dir(?APPNAME) of
{error, bad_name} ->
case filelib:is_dir(filename:join(["..", priv])) of
true ->
filename:join(["..", priv, ?LIBNAME]);
_ ->
filename:join([priv, ?LIBNAME])
end;
Dir ->
filename:join(Dir, ?LIBNAME)
end,
erlang:load_nif(SoName, 0).
not_loaded(Line) ->
erlang:nif_error({not_loaded, [{module, ?MODULE}, {line, Line}]}).
repeat(_, _) ->
not_loaded(?LINE).
配置hooks(方便构建cmake项目)
rebar.config
{pre_hooks,
[{"(linux|darwin|solaris)", compile, "make -C c_src"},
{"(freebsd)", compile, "gmake -C c_src"}]}.
{post_hooks,
[{"(linux|darwin|solaris)", clean, "make -C c_src clean"},
{"(freebsd)", clean, "gmake -C c_src clean"}]}.
调用
- 启动
直接基于rebar3 的shell 命令
rebar3 shell
效果
- 调用方法
myapp:repeat(self(),dalong).
receive X -> X end.
效果
说明
rebar3 提供的cli 还是比较方便,可以方便的进行构建
参考资料
https://rebar3.org/docs/tutorials/building_c_cpp/
https://rebar3.org/docs/configuration/configuration/#hooks
https://www.erlang.org/doc/man/erl_nif
https://github.com/rongfengliang/rebar_cmake_erlang
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2020-12-22 jinjava一个不错的java jinja2 模版引擎
2020-12-22 pmm2.12.0 运行
2020-12-22 pmm-agent 源码编译
2020-12-22 pmm 2.13 技术预览版支持报警
2020-12-22 pmm 2.12.0 新架构介绍
2020-12-22 Qovery/engine 多云部署引擎
2018-12-22 vernemq 集群 docker-compose 搭建简单试用