h2xs - 将 .h C 头文件转换为 Perl 扩展
h2xs [选项 ...] [头文件 ... [额外库]]
h2xs -h|-?|--help
h2xs 从 C 头文件构建 Perl 扩展。扩展将包含可用于检索 C 头文件中任何 #define 语句的值的函数。
模块名称 将用于扩展的名称。如果未提供模块名称,则将使用第一个头文件的名称,并将第一个字符大写。
如果扩展可能需要额外的库,则应在此处包含它们。扩展的 Makefile.PL 将负责检查库是否实际存在以及如何加载它们。额外的库应以 -lm -lposix 等形式指定,就像在 cc 命令行中一样。默认情况下,Makefile.PL 将搜索 Configure 确定的库路径。可以通过在额外库参数中包含 -L/another/library/path 形式的参数来扩展该路径。
尽管它的名字是 h2xs,它也可以用来创建一个纯 Perl 模块的骨架。请参阅 -X 选项。
省略所有自动加载功能。这与 -c 相同,但还会从 .pm 文件中删除 use AutoLoader
语句。
使用 alpha/beta 风格的版本号。除非指定 -v,否则版本号将为 "0.00_01"。
省略 Changes 文件的创建,并在 POD 模板中添加一个 HISTORY 部分。
在扫描头文件以查找函数声明时,要指定给 C 预处理器的附加标志。也会在生成的 Makefile.PL 中写入这些选项。
选择要处理的函数/宏。
允许覆盖预先存在的扩展目录。
省略自动生成的存根 POD 部分。
省略 XS 部分。用于生成一个纯 Perl 模块的骨架。-c
和 -f
会隐式启用。
为结构体和联合体的每个元素生成一个访问器方法。生成的访问器方法以元素名称命名;如果在没有附加参数的情况下调用,则会返回元素的当前值;如果在调用时带有附加参数,则会将元素设置为提供的参数(并返回新值)。嵌入的结构体和联合体将作为指针返回,而不是完整的结构体,以方便链式调用。
这些方法都适用于结构体的 Ptr 类型;此外,还为结构体类型本身构建了两个方法,_to_ptr
返回指向同一结构体的 Ptr 类型,以及一个 new
方法来构造并返回一个新的结构体,初始化为零。
生成一个与指定的 Perl 版本向后兼容的 .pm 文件。
对于版本 < 5.6.0,更改如下。 - 不使用 'our'(而是使用 'use vars') - 不使用 'use warnings'
指定高于运行 h2xs 的 Perl 版本的兼容性版本将无效。如果未指定,h2xs 将默认与运行 h2xs 的 Perl 版本兼容。
从 .xs 文件中省略 constant()
,并从 .pm 文件中省略相应的专用 AUTOLOAD
。
打开调试消息。
如果未给出正则表达式,则跳过在 C 枚举中定义的所有常量。否则,仅跳过在名称与正则表达式匹配的枚举中定义的常量。
由于正则表达式是可选的,因此请确保如果省略正则表达式并且有一些待处理的参数(例如头文件名称),则此开关后至少跟随一个其他开关。这是可以的
h2xs -e -n Module::Foo foo.h
这是不行的
h2xs -n Module::Foo -e foo.h
在后者中,foo.h 被视为正则表达式。
允许为头文件创建扩展,即使该头文件在标准包含目录中找不到。
在 .xs 文件中包含用于安全存储静态数据的代码。不使用静态数据的扩展可以忽略此选项。
打印此 h2xs 的用法、帮助和版本,然后退出。
对于声明为 const
的函数参数,在生成的 XS 代码中省略 const 属性。
实验性:对于在头文件中声明的每个变量,声明一个与 C 变量神奇绑定名称相同的 Perl 变量。
指定扩展的名称,例如:-n RPC::DCE
对于与正则表达式匹配的 C 类型,即使这些类型是 typedef
等效于类型映射中的类型,也使用“不透明”数据类型。不应在没有 -x 的情况下使用。
这可能很有用,因为例如,与整数 typedef
等效的类型可能代表与操作系统相关的句柄,并且可能希望以面向对象的方式使用这些句柄,例如 $handle->do_something()
。如果要将所有 typedef
ed 类型处理为不透明类型,请使用 -o .
。
要匹配的类型将被清洗(除了逗号,逗号前面没有空格,以及多个 *
,它们之间没有空格)。
指定应从 Perl 函数名中删除的前缀,例如:-p sec_rgy_ 这将设置 XS PREFIX 关键字,并从通过 constant()
机制自动加载的函数中删除前缀。
为指定的宏创建一个 Perl 子例程,而不是使用 constant() 子例程自动加载。假设这些宏的返回类型为 char *,例如:-s sec_rgy_wildcard_name,sec_rgy_wildcard_sid.
指定 constant() 机制为宏使用的内部类型。默认值为 IV(带符号整数)。目前,在头文件扫描过程中找到的所有宏都将被假定为具有此类型。h2xs
的未来版本可能会获得进行有根据猜测的能力。
当存在--compat-version (-b) 时,生成的测试将使用Test::More
而不是Test
,Test
是 5.6.2 之前版本的默认值。Test::More
将被添加到生成的Makefile.PL
中的 PREREQ_PM 中。
将强制生成使用旧的Test
模块的测试代码。
不要使用Exporter
以及导出任何符号。
不要使用Devel::PPPort
:无法移植到旧版本。
不要使用模块AutoLoader
;但保留常量() 函数和sub AUTOLOAD
用于常量。
不要使用strict
编译指示。
不要使用warnings
编译指示。
为该扩展指定版本号。此版本号将添加到模板中。默认值为 0.01,如果指定了-B
,则为 0.00_01。指定的版本应为数字。
根据头文件中的函数声明自动生成 XSUB。C::Scan
包应该已安装。如果指定了此选项,头文件名称可能类似于NAME1,NAME2
。在这种情况下,使用 NAME1 代替指定的字符串,但仅针对从文件 NAME2 包含的声明发出 XSUB。
请注意,某些类型的函数参数/返回值可能会导致需要手动编辑的 XSUB 声明/类型映射条目。例如,无法从指针转换或转换为指针的对象(如long long
)、指向函数的指针或数组。另请参阅关于"-x 的限制" 的部分。
# Default behavior, extension is Rusers
h2xs rpcsvc/rusers
# Same, but extension is RUSERS
h2xs -n RUSERS rpcsvc/rusers
# Extension is rpcsvc::rusers. Still finds <rpcsvc/rusers.h>
h2xs rpcsvc::rusers
# Extension is ONC::RPC. Still finds <rpcsvc/rusers.h>
h2xs -n ONC::RPC rpcsvc/rusers
# Without constant() or AUTOLOAD
h2xs -c rpcsvc/rusers
# Creates templates for an extension named RPC
h2xs -cfn RPC
# Extension is ONC::RPC.
h2xs -cfn ONC::RPC
# Extension is a pure Perl module with no XS code.
h2xs -X My::Module
# Extension is Lib::Foo which works at least with Perl5.005_03.
# Constants are created for all #defines and enums h2xs can find
# in foo.h.
h2xs -b 5.5.3 -n Lib::Foo foo.h
# Extension is Lib::Foo which works at least with Perl5.005_03.
# Constants are created for all #defines but only for enums
# whose names do not start with 'bar_'.
h2xs -b 5.5.3 -e '^bar_' -n Lib::Foo foo.h
# Makefile.PL will look for library -lrpc in
# additional directory /opt/net/lib
h2xs rpcsvc/rusers -L/opt/net/lib -lrpc
# Extension is DCE::rgynbase
# prefix "sec_rgy_" is dropped from perl function names
h2xs -n DCE::rgynbase -p sec_rgy_ dce/rgynbase
# Extension is DCE::rgynbase
# prefix "sec_rgy_" is dropped from perl function names
# subroutines are created for sec_rgy_wildcard_name and
# sec_rgy_wildcard_sid
h2xs -n DCE::rgynbase -p sec_rgy_ \
-s sec_rgy_wildcard_name,sec_rgy_wildcard_sid dce/rgynbase
# Make XS without defines in perl.h, but with function declarations
# visible from perl.h. Name of the extension is perl1.
# When scanning perl.h, define -DEXT=extern -DdEXT= -DINIT(x)=
# Extra backslashes below because the string is passed to shell.
# Note that a directory with perl header files would
# be added automatically to include path.
h2xs -xAn perl1 -F "-DEXT=extern -DdEXT= -DINIT\(x\)=" perl.h
# Same with function declaration in proto.h as visible from perl.h.
h2xs -xAn perl2 perl.h,proto.h
# Same but select only functions which match /^av_/
h2xs -M '^av_' -xAn perl2 perl.h,proto.h
# Same but treat SV* etc as "opaque" types
h2xs -o '^[S]V \*$' -M '^av_' -xAn perl2 perl.h,proto.h
假设您有一些实现某些功能的 C 文件,以及相应的头文件。如何创建一个扩展,使这些功能在 Perl 中可用?以下示例假设头文件为 interface_simple.h 和 interface_hairy.h,并且您希望 Perl 模块命名为 Ext::Ension
。如果您需要一些预处理器指令和/或与外部库的链接,请参阅 "OPTIONS" 中的标志 -F
、-L
和 -l
。
从 h2xs 的一个虚拟运行开始
h2xs -Afn Ext::Ension
此步骤的唯一目的是创建所需的目录,并让您知道这些目录的名称。从输出中您可以看到扩展的目录是 Ext/Ension。
将您的头文件和 C 文件复制到此目录 Ext/Ension。
运行 h2xs,覆盖旧的自动生成文件
h2xs -Oxan Ext::Ension interface_simple.h interface_hairy.h
h2xs 在更改到扩展目录后查找头文件,因此它会找到您的头文件。
像往常一样,运行
cd Ext/Ension
perl Makefile.PL
make dist
make
make test
尽早执行 make dist
非常重要。这样,如果您决定编辑您的 .h
文件并重新运行 h2xs,您可以轻松地将您的更改合并(1)到自动生成的文件中。
不要忘记编辑生成的 .pm 文件中的文档。
将自动生成的文件视为骨架,您可以发明比 h2xs 猜测更好的接口。
将本节视为仅供参考,h2xs 的其他一些选项可能更适合您的需求。
不使用任何环境变量。
Larry Wall 及其他人
perl、perlxstut、ExtUtils::MakeMaker 和 AutoLoader。
如果无法读取或写入相关文件,则会显示通常的警告。
h2xs 无法区分 C 函数的参数(例如 int *
)是输入参数、输出参数还是输入/输出参数。特别是,以下形式的参数声明
int
foo(n)
int *n
应该改写为
int
foo(n)
int &n
如果 n
是输入参数。
此外,h2xs 无法推断出函数
int
foo(addr,l)
char *addr
int l
接受该地址处的数据地址和长度对,因此最好将此函数改写为
int
foo(sv)
SV *addr
PREINIT:
STRLEN len;
char *s;
CODE:
s = SvPV(sv,len);
RETVAL = foo(s, len);
OUTPUT:
RETVAL
或者
static int
my_foo(SV *sv)
{
STRLEN len;
char *s = SvPV(sv,len);
return foo(s, len);
}
MODULE = foo PACKAGE = foo PREFIX = my_
int
foo(sv)
SV *sv