erlang+-c语言程序接口.pdf_第1页
erlang+-c语言程序接口.pdf_第2页
erlang+-c语言程序接口.pdf_第3页
erlang+-c语言程序接口.pdf_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Erlang 可以和多种程序语言连接 比如 C 语言 java 语言等 一般来讲 A 语言有两种方 式可以调用 B 语言设计的程序 第一种 把 B 语言的可执行二进制代码拷贝到 A 程序中 定义标准的参数调用接口 从而 B 程序执行的结果返回到 A 程序中 第二种 两个独立 的进程 A 进程可以和 B 进程通信 在 Erlang 中 采用的是第二种方法 本文中 我们就 讲解 Erlang 和 C 语言的接口 首先要弄清楚 和 C 语言交互数据的方法之一是采用 标准输入输出 比如你可以通 过控制台 Dos 给 C 程序输入一个值 并再回显 Erlang 虚拟机的底层驱动实现了代替 标 准输入输出 的功能 这就是 Erlang 和 C 程序传递数据的底层原理 你可能想知道 底层 是如何实现这个的呢 这与 Windows 操作系统以及驱动有关系 我们暂时先不用管它 好了 我们先来写一个 C 程序 代码如下 include stdafx h include int tmain int argc TCHAR argv int fn arg1 arg2 result char buff 100 int len while len read 0 buff 4 0 arg1 buff 2 arg2 buff 3 result arg1 arg2 buff 0 0 buff 1 1 buff 2 result write 1 buff 3 逐个来看吧 stdafx h 包含了 windows 的一些函数库 叫做 Afx 函数库 定义了很多函 数 包括 tmain 函数 传统的 C 语言使用的是 main 函数 io h 文件包含了从一个标准输入输出设备上读取数据的函数 包括 read write 函数 大家可以在 MSDN 上查一下 read 和 wirte 函数的定义 这里你只需要知道 read 的第一 个参数的含义 当第一个参数为 0 时 意味着输入 为 1 时表示输出 其它两个参数一个缓 冲区指针 另一个是字节长度 你可以编译并运行一下 然后单步跟踪一下 运行时 会弹出一个控制台 要你输入一 段字符 然后 它再回显 3 个字符 你可以输入 1234 然后回车 试一下 再单步跟踪一下 看看 相信这段代码的逻辑你肯定能明白 可问题是为什么要用这样一个古怪的 C 程序进 行学习呢 好 现在我就来解释 Erlang 把和所有外部程序 比如 C 程序 交互数据的方法交给 Port 去完成 因此 当你 的 Erlang 代码想调用外部的 C 程序时 首先需要创建一个端口 Erlang 提供了创建端口的 函数 YourPort open port PortName PortSettings 先别管参数的定义 每个端口必须绑定到一个 Erlang 进程中 一般来讲 创建 Erlang 端口的进程即为端口连接进程 创建号端口后 你就可以向该端口发送数据 或者从端口读 取数据 YourPort Pid command Data 该命令向端口名 YourPort 发送数据 Data 其中 Pid 是端口连接进程 receive YourPort data Data 当发送完数据后 如果外部程序有返回 那么上面代码可以读到返回的数据 Data 你可能会奇怪 为什么向端口发送数据的函数还要包括 端口管理进程 呢 YourPort Pid command Data 为什么不能改为 YourPort command Data 其实我 也很纳闷 为什么创建一个端口后 端口不能独立于所谓的 端口管理进程 我不是 Erlang 的发明人 暂时也不清楚 那就先别管了 我们记住这个规则就好了 正因为有这样的规则 Erlang 才提供了另外一个函数 YourPort Pid1 connect Pid2 该命令把 YourPort 端口的连接管理进程从 Pid1 改为 Pid2 最后 Erlang 还提供了关闭一个端口的函数 YourPort Pid close 当然 这只是关闭一个端口 而没有关闭那个 连接管理进程 我感觉 所谓的 连 接管理进程 只是一个名义上的管理 因为 Erlang 没有给我们暴露任何函数去改变 管理 的细节 关闭一个端口的本质是 Erlang 向外部程序发送一个空字节 因此 如果外部程序 试图读取输入的时候 读取的字节长度为 0 另外 大家要知道这样一个事实 即 shell 本身也是 Erlang 的一个进程 你可以在 shell 的命令行中输入 self 你可以看到返回值 改函数的作用是显示本线程的 ID 你可以把该函数写在代码中 表 示 Pid 接下来 我绘制一下本例子的流程 首先 shell 进程创建一个端口 外部 C 程序完成一个加法函数操作 并把结果返回给端 口 shell 进程把返回的结果显示出来 Erlang 端的代码如下 Shell 进程 Port 外部 C 程序 startPort register myfuc self process flag trap exit true open port spawn c fun2 exe packet 2 getData Port X Y Port self command X Y receive Port data Data Data end stopPort Port Port self close receive Port closed exit iloveyou end startPort 函数是创建了一个端口 调用函数 open port 请你注意其中的参数 spawn 基 本上是固定的关键字 第二项是对应的 exe 文件的路径 最后一项 packet 2 是告诉 erlang 端口驱动 发送数据时 给数据头部增加一个长度标记 长度用两个字节表示 比如 如果 要发送 1 2 3 三个数据 那么 实际上发出的数据将会变为 0 3 1 2 3 其中前面的 0 3 代表了数据的长度 register 函数用于向系统注册一个进程别名 以后 可以用该别名引用该进程 process flag 的含义我没有深究 有兴趣的朋友可以查看手册 getData 函数的作用是向外部 C 程序发送两个数值 X Y 并期望外部 C 程序完成一个加 法 并把数据返回 stopPort 的作用则是关闭一个端口 以上这个例子都是调用 Erlang 提供的那 4 个标准的函数 很好理解 但是 你可能对参 数的大括弧和中括弧有点头晕 这就是序列和列表的使用方法 我再稍微总结一下 序列的 数据大小是固定的 一旦定义好之后不可改变 而列表的大小是随时可以改变 序列和列表 都可以当作函数参数 一般来讲 如果你所定义函数的参数个数是固定值 那么可以使用列 表 也可以使用序列 但是 当你的函数参数个数不定时 则必须使用列表 比如上面的发送数据函数 Port self command X Y 其中 X Y 就是按照列表方式 定义的 原因是发送数据的大小是个变数啊 你可以写成 Port self command X Y Z W Q 编写完以上代码后 别忘了在文件头部加上函数导出说明 如下 export getData 3 startPort 0 stopPort 1 这是一种简洁的写法 大家可以看到 export 函数的内部参数也是使用列表 因为可以变化 懂得了这个道理 相信你以后会更理解参数何时使用 何时使用 现在可以解释上面 C 函数那样怪异的原因了 本例中 Erlang 希望外部 C 程序完成一个 加法操作 给外部 C 程序发送的数据为 0 2 X Y 4 个字节 而在 C 代码中 len read 0 buff 4 语句会从标准输入上读 4 个字节存入 buff 中 如果 C 程序读取的字节数不大于 0 则意味 着非正常情况的发生 则可以自己退出 事实上 当执行 Erlang 的 stopPort 代码时 Erlang 向外部程序发送了一个 0 字节长度的数据 这也会告知 C 程序退出 C 程序解析读到的 4 个字节后 从第三 四个字节中取出 X Y 然后运行加法后 再 把结果返回给 Erlang 这里要注意的是 实际上 C 返回的数据为 0 1 result 这是因为 Erlang 的端口驱动定义的数据传输格式是 前两个字节表示后续的字节长度 open port 参数中 paceket 2 的作用 这就意味着 最大传输的字节长度为 64K 2 的 16 次方 好了 现在开始运行一下 首先把编译好的 C 程序代码拷贝到 erl 目录下 我的 C 程序 名字为 c fun2 exe c prac 重新编译代码 MyPort prac startPort 调用 startPort 函数 返回这为端口 ID 注意不同于进程 ID prac getData MyPort 10 23 你可以多试几组数据 prac getData MyPort 20 90 此时 你可以查看任务管理器中 c fun2 exe 正在运行 这意味着 c fun2 exe 完全以独 立进程的方式被启动的 prac stopPort MyPort 此时你可以再看任务管理器 发现 c fun2 exe 已经没有了 事实上不是 Erlang 有什么特 异功能把 c fun2 exe 给杀死了 而是 c fun2 exe 收到的字节数为 0 而

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论