首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何实现Erlang驱动程序作为默认高效实现

如何实现Erlang驱动程序作为默认高效实现
EN

Stack Overflow用户
提问于 2021-11-12 15:09:43
回答 1查看 70关注 0票数 0

Erlang运行时系统( Erlang Run-Time System,ERTS )有一些用C语言编写的驱动程序,用于与操作系统交互或访问低级资源,据我所知,ERTS在启动时编译这些驱动程序以准备从Erlang代码加载,驱动程序inet_drv.c就是其中之一,它用于处理网络任务,如创建套接字、侦听或接受新的传入连接。

我想手动测试这个驱动程序,以了解ERTS的默认行为,并了解如何在将来高效地实现驱动程序。我跟踪Erlang手册引用来实现驱动程序:首先用OS C语言编译器编写和编译驱动程序,第二次使用erl_ddll模块从erlang代码加载驱动程序,最后通过生成的Erlang进程链接到驱动程序,所以这非常简单和容易。

因此,我尝试使用驱动程序inet_drv.c执行以下步骤,然后搜索并尝试用Compiler编译它,Compiler是FreeBSD系统的默认C编译器:

代码语言:javascript
复制
cc inet_drv.c

在此之后,出现了一个错误,即没有定义文件erl_driver.h,该头文件在驱动程序的代码中用作包含的文件(#include<erl_driver.h>),因此我搜索它并使用-I选项将它的目录路径添加到cc命令中,让编译器搜索该目录中包含的文件,然后重新编译它:

代码语言:javascript
复制
cc inet_drv.c -I/usr/ports.... 

在此之后,还有另一个未定义的文件,因此我执行了5或6次相同的操作,最后,我为包含的文件添加了所有所需的路径,结果是这样的命令:

代码语言:javascript
复制
cc inet_drv.c

-I/usr/ports/lang/erlang/work/otp-OTP-21.3.8.18/erts/emulator/beam

-I/usr/local/lib/erlang/usr/include

-I/usr/ports/lang/erlang/work/otp-OTP-21.3.8.18/erts/emulator/sys/unix

-I/usr/ports/lang/erlang/work/otp-OTP-21.3.8.18/erts/include/internal

-I/usr/ports/lang/erlang/work/otp-OTP-21.3.8.18/erts/emulator/sys/common

-I/usr/ports/lang/erlang/work/stage/usr/local/lib/erlang/erts-10.3.5.14/include/internal

我对结果感到惊讶:13个错误和7个警告,shell输出以及错误和警告描述都在下面的链接中。我的问题是:为什么会发生这些错误?我做的事有什么不对?

由于这个驱动程序能够很好地响应ERTS网络任务,所以它由ERTS编译而没有错误,ERTS应该使用默认情况下是Clang的OS C语言编译器,并且应该像我一样添加包含的头文件,那么为什么当我尝试这样做时,它不能工作呢?

https://ibb.co/bbtFHZ7

https://ibb.co/sF8QsDx

https://ibb.co/Lh9cDCH

https://ibb.co/W5Gcj7g

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-12 16:25:00

首先要做的是:

据我所知,ERTS在引导时编译这些驱动程序。

不,ERTS不编译驱动程序。inet_drv.c作为Erlang/OTP的一部分编译,并链接到beam.smp二进制文件中。

inet_drv不是典型的驱动程序。引用文档的如何实现驱动程序部分:

驱动程序可以作为共享库(在Windows上称为DLL )动态加载,或者在编译和链接时以静态方式与模拟器链接。这里只描述了动态加载的驱动程序,静态链接驱动程序超出了本节的范围。

inet_drv是一个静态加载的驱动程序,因此不需要使用erl_ddll加载。

继续编译错误。在运行make时,所有编译器参数都会自动添加,因此,如果需要手动调用编译器,最好检查make生成的命令行并从此开始。让我们看看Debian Erlang包的构建日志。在搜索inet_drv时,我们得到了这个命令行(添加了行中断):

代码语言:javascript
复制
x86_64-linux-gnu-gcc -Werror=undef -Werror=implicit -Werror=return-type  -fno-common \
  -g -O2 -fno-strict-aliasing -I/<<PKGBUILDDIR>>/erts/x86_64-pc-linux-gnu    -D_GNU_SOURCE \
  -DHAVE_CONFIG_H -Wall -Wstrict-prototypes -Wpointer-arith -Wmissing-prototypes \
  -Wdeclaration-after-statement -DUSE_THREADS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS \
  -D_POSIX_THREAD_SAFE_FUNCTIONS   -DBEAMASM=1 -DLIBSCTP=libsctp.so.1 \
  -Ix86_64-pc-linux-gnu/opt/jit -Ibeam -Isys/unix -Isys/common -Ix86_64-pc-linux-gnu \
  -Ipcre -I../include -I../include/x86_64-pc-linux-gnu -I../include/internal \
  -I../include/internal/x86_64-pc-linux-gnu -Ibeam/jit -Ibeam/jit/x86 -Idrivers/common \
  -Idrivers/unix -c \
  drivers/common/inet_drv.c -o obj/x86_64-pc-linux-gnu/opt/jit/inet_drv.o

由于您构建在FreeBSD上,所以其中的一些不同之处在于,但原则是成立的--大多数时候您只想运行make而不是直接调用编译器,但是如果您需要调用编译器,那么从make为您生成的命令行开始就会容易得多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69945022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档