`
langzhe
  • 浏览: 288250 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

erlang 通过nif调用C 程序 (erlang调用C程序的问题)

 
阅读更多

1、

erlang调用C程序的问题,
我采用的是nif方式
代码片段:
char *y;
if (!enif_get_string(env, argv[0], y, sizeof(y), ERL_NIF_LATIN1))
我采用上面方法得到y是“123”,实际erlang传入的参数"123456"
如果我把sizeof(y) 修改成 10在erlang下会出现Segmentation fault错误提示,请问 为什么

我的提问: (不确定以下英文是否完全正确)

hi,

I using nif mehod to Invoke C funtion in Erlang.
come code:
1,
char *y;
if (!enif_get_string(env, argv[0], y, sizeof(y), ERL_NIF_LATIN1)) 
  
I input "123456" args, but only return "123".

2,char *y;
if (!enif_get_string(env, argv[0], y, 10, ERL_NIF_LATIN1)) 

this only appear Segmentation fault

I have no idea.
Please help me. 

Thanks.
From jason.

网友的回复

"char *y" is actually just a pointer, so sizeof(y) returns 4, which is
a size of the pointer. Since you don't know how long is the string,
you should prepare a big enough buffer to receive it. So try the
following code:

#define MAXBUFLEN       1024

char y[MAXBUFLEN];
if (enif_get_string(env, argv[0], y, MAXBUFLEN, ERL_NIF_LATIN1) < 1)
   return enif_make_badarg(env);

 

> Thanks Gleb Peregud.
>
> Your are right. But a new request is come on. I input list [1,7,0,9] as
> parameter. Ii only return [1,7]. The [0,9] is lose. Maybe the '0' elment as
> a NUL in C.
> What  should i do .
>
> Thanks
>
> 8>complex6:get_name([1,7,0,9]).
> [1,7]
> 9>

Most probably enif_get_string does copy all four bytes to the buffer,
but enif_make_string treats NUL as termination mark of a string. Try
using enif_make_string_len instead.

On the other side it looks like you are interested in a binary-like
data, instead of a string-like data. You can make use of the following
code:

ErlNifBinary input;
if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) {
 return enif_make_badarg(env);
}

As the result of this:
input.data - will contain pointer to a memory, where all bytes from
argument are stored
input.size - size of that memory area

Also it's worth noting that this will work for both lists (with
integers less than 256) and binaries, and for any nested combinations
of them.

hi, Gleb Peregud, Thanks to  your help. My quest is solved. 

 56     ErlNifBinary input;
 57     if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) {
 58      return enif_make_badarg(env); 
 59     }
 60     char *y="yy";
 61     unsigned char* a=input.data;   
 62     int i=0;
 63     //test                                                                                                                                        
 64     while(i<input.size){
 65         fprintf(stderr,"a=%i,", a[i]);
 66         i++;
 67         //fprintf(stderr,"a=%i\n\r", *a);
 68         //a++;
 69     }
 70     fprintf(stderr,"input.size=%i\n\r", input.size);
 71     fprintf(stderr,"input.data=%s\n\r", input.data);
 72     //return enif_make_string(env, a, ERL_NIF_LATIN1);
 73     return enif_make_string_len(env, a, i,ERL_NIF_LATIN1);


Thanks agin.

from jason

 

//

  1 #include "erl_nif.h"                                                       
  2 #include "unistd.h"
  3 #include "stdio.h"
  4 #include <string.h>
  38 static ERL_NIF_TERM get_name_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE    RM argv[])
  39 {
  56     ErlNifBinary input;
  57     if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) {
  58      return enif_make_badarg(env);
  59     }
  60     char *y="yy";
  61     unsigned char* a=input.data;
  62     int i=0;
  63     //test 
  64     while(i<input.size){
  65         fprintf(stderr,"a=%i,", a[i]);
  66         i++;
  67         //fprintf(stderr,"a=%i\n\r", *a);
  68         //a++;
  69     }
  70     fprintf(stderr,"input.size=%i\n\r", input.size);                       
  71     fprintf(stderr,"input.data=%s\n\r", input.data);
  72     //return enif_make_string(env, a, ERL_NIF_LATIN1);
  73     return enif_make_string_len(env, a, i,ERL_NIF_LATIN1);
  74 //----------------------
  102 }
134 static ErlNifFunc nif_funcs[] = {
138     {"get_name", 1, get_name_nif}
140 };
141 ERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)


//
%%

  1 -module(complex6).                                                         
  2 -export([foo/1, bar/1,
  3          get_name/2,
  4          get_name/1,
  5          get_list/1,
  6          test_lxw/2]).
  7 -on_load(init/0).
  8 init() ->
  9     ok = erlang:load_nif("./complex6_nif", 0).

 16 get_name(_X) ->
 17     ok.

编译
gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c

41> c(complex6).
{ok,complex6}

43> complex6:get_name([1,0,2,0,3,4]).
a=1,a=0,a=2,a=0,a=3,a=4,input.size=6
[1,0,2,0,3,4]                                                                  44>



 

 

------------问题总算有结果了。。

官方文档:http://www.erlang.org/doc/tutorial/c_port.html

0
1
分享到:
评论

相关推荐

    rustler编写erlang nif

    在Erlang生态系统中,Native Implemented Functions (NIFs) 是一种机制,允许开发者用其他语言(如C、C++或Rust)编写性能关键部分的代码,然后在Erlang虚拟机(VM)中调用。Rustler是一个库,专门用于简化使用Rust...

    erlang nif test

    NIFs是Erlang与C交互的重要手段,它允许Erlang代码调用C函数,执行无法或不适合在Erlang虚拟机(VM)上进行的计算任务,比如硬件操作、加密算法或者高性能的数据处理。 创建一个Erlang NIF通常涉及以下几个步骤: ...

    erl_nif_rustler_过程宏写法

    `my_function`就是你的NIF,它接收一个`Env`参数,用于与ErlangVM交互,以及一个`args`参数,包含Erlang调用时传入的参数列表。`NifResult&lt;Term&gt;`表示该函数可能返回的Erlang术语或错误。 为了将Rust编译成Erlang可...

    erl_nif 扩展erlang的另外一种方法

    当Erlang加载这个模块时,会调用C库中的初始化函数,进行必要的设置和资源分配。 3. **生命周期管理**:NIFs需要处理生命周期问题,例如在加载、卸载模块时释放资源。这包括在加载时调用`enif_open_nif`,在卸载时...

    bitwise:用于显示Erlang调度程序问题的Erlang NIF示例

    按位:NIF示例显示Erlang调度程序的问题bitwise模块实现了几个Erlang本机实现函数(NIF),旨在显示NIF对Erlang调度程序线程可能产生的几种不同影响。 该模块提供的功能的几个变体exor/2采用一个二进制和一个字节值...

    nimler:Nim中的ErlangElixir NIF

    NIF是Erlang虚拟机(BEAM)的一个特性,允许Erlang和Elixir程序调用C编写的库,从而提升性能并引入了与操作系统或硬件更紧密集成的能力。nimler项目将这一功能扩展到了Nim语言,让Nim开发者也能利用这一优势。 Nim...

    erlang-rust-nif:在 Rust 中实现的 Erlang NIF 示例

    Rust 中的 Erlang NIF 这是一个如何在 Rust 中实现 NIF 的示例。 它对我有用,也可能对你有用,但如果它吃掉了你的作业,请不要生气。 虽然这将是可行的写现实世界的代码下面这个例子,因为整个erl_nif.h接口可用...

    erlang port driver test

    在 Erlang 中,Port Driver 是一种机制,允许 Erlang 进程与外部 C 库或者其他语言编写的程序进行通信。Port Driver 提供了一种方式,使得 Erlang 系统能够与外部世界交互,执行低级别的I/O操作或调用非Erlang代码...

    erlang-tc:Erlang NIF用于threshold_crypto

    1. **构建**:通过运行`make`命令,这将调用Makefile中定义的规则来编译C代码(通常包括NIF的实现)并与Erlang模块链接。编译后的NIF库会被Erlang加载,使得Erlang代码能够调用这些原生函数。 2. **测试**:使用`...

    esqlite:sqlite的Erlang NIF

    硬玉 sqlite3的Erlang nif库。 介绍 该库允许您使用来自erlang的出色的sqlite引擎。... 这是通过在轻量级线程中处理来自erlang的所有命令来完成的。 将命令添加到线程的命令队列后,erlang调度程序将重新获得控制权。

    rustler:用于创建Erlang NIF函数的Safe Rust桥

    NIF是Erlang虚拟机(VM)提供的一种机制,使得Erlang代码能够调用C或C++编写的库,从而利用这些语言的高性能特性。Rustler的出现,将这种能力扩展到了Rust,为开发者提供了更多优势。 Rust是一种系统级编程语言,以...

    用于创建 Erlang NIF 函数的安全 Rust 桥

    该库提供了用于生成与 BEAM 交互的样板的工具,处理 Erlang 术语的编码和解码,并在它们展开为 C 之前捕获 Rust 恐慌。该库为 Erlang 和 Elixir 提供了功能,但目前 Elixir 受到青睐。特征:安全 - 您在 Rust NIF 中...

    enif_protobuf:使用enif(Erlang nif)的Google Protobuf实现

    2. **性能提升**:由于NIFs允许直接调用C/C++代码,所以使用enif_protobuf比纯Erlang实现更高效,特别是在处理大量数据时。 3. **易用性**:enif_protobuf提供了简洁的Erlang API,使得开发者能够以Erlang风格编写...

    niffed:使用来自 erlang 驱动程序的 nifs,或双 nifdriver 代码

    你被嘲笑了 niffed 是一个包装器,可让您在 Erlang 驱动程序中使用 nif API。... nif 调用是通过驱动程序控制接口通过简单的调度程序进行的。 这使得将 nif 代码移植到驱动程序中(反之亦然)更简单一些。

    luex:Nif在Erlang中运行Lua

    在Elixir / Erlang中运行lua 安装 如果,包装可以通过添加安装luex你在依赖列表mix.exs : def deps do [ { :luex , " ~&gt; 0.1.0 " } ] end 用法示例 { :ok , l} = Luex . init () Luex . dostring (l, " while...

    Python-Ecache是一个基于erlangnifleveldbprotobuf构建的轻量级高效没有容量限制的本地磁盘缓存系统

    Erlang NIF是Erlang虚拟机的一个特性,允许Erlang程序调用C或C++编写的原生代码,从而提高性能。在Ecache中,NIF被用来桥接Erlang和Python,使得Python程序能够直接与Erlang的高效并发机制交互,同时利用Erlang的...

    elixir-opencv:用于ErlangElixir的OpenCv NIF绑定

    Elixir是一种基于Erlang虚拟机的函数式编程语言,而NIF(Native Implemented Functions)是Erlang的一种特性,允许编写C或C++代码来提升性能。通过NIF绑定,Elixir开发者可以直接在Elixir应用中调用OpenCV的功能,而...

    E里面直接写汇编.rar

    在实际应用中,Erlang通常会通过NIF(Native Implemented Functions)机制来调用C/C++代码,这些C/C++代码可以包含汇编部分,以实现与Erlang VM交互的高性能模块。NIF允许Erlang程序调用本地代码,同时保持Erlang的...

    Rustler

    4. 在Erlang项目中,通过NIF接口调用Rust代码。 5. 编译Rust项目并将其链接到Erlang应用中。 在游戏开发中,Rustler可以用来编写高性能的游戏逻辑,例如物理引擎、图形渲染或AI算法,这些部分往往需要低级别的控制...

Global site tag (gtag.js) - Google Analytics