内容

名称

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 选项。

选项

-A, --omit-autoload

省略所有自动加载功能。这与 -c 相同,但还会从 .pm 文件中删除 use AutoLoader 语句。

-B, --beta-version

使用 alpha/beta 风格的版本号。除非指定 -v,否则版本号将为 "0.00_01"。

-C, --omit-changes

省略 Changes 文件的创建,并在 POD 模板中添加一个 HISTORY 部分。

-F, --cpp-flags=addflags

在扫描头文件以查找函数声明时,要指定给 C 预处理器的附加标志。也会在生成的 Makefile.PL 中写入这些选项。

-M, --func-mask=正则表达式

选择要处理的函数/宏。

-O, --overwrite-ok

允许覆盖预先存在的扩展目录。

-P, --omit-pod

省略自动生成的存根 POD 部分。

-X, --omit-XS

省略 XS 部分。用于生成一个纯 Perl 模块的骨架。-c-f 会隐式启用。

-a, --gen-accessors

为结构体和联合体的每个元素生成一个访问器方法。生成的访问器方法以元素名称命名;如果在没有附加参数的情况下调用,则会返回元素的当前值;如果在调用时带有附加参数,则会将元素设置为提供的参数(并返回新值)。嵌入的结构体和联合体将作为指针返回,而不是完整的结构体,以方便链式调用。

这些方法都适用于结构体的 Ptr 类型;此外,还为结构体类型本身构建了两个方法,_to_ptr 返回指向同一结构体的 Ptr 类型,以及一个 new 方法来构造并返回一个新的结构体,初始化为零。

-b, --compat-version=version

生成一个与指定的 Perl 版本向后兼容的 .pm 文件。

对于版本 < 5.6.0,更改如下。 - 不使用 'our'(而是使用 'use vars') - 不使用 'use warnings'

指定高于运行 h2xs 的 Perl 版本的兼容性版本将无效。如果未指定,h2xs 将默认与运行 h2xs 的 Perl 版本兼容。

-c, --omit-constant

从 .xs 文件中省略 constant(),并从 .pm 文件中省略相应的专用 AUTOLOAD

-d, --debugging

打开调试消息。

-e, --omit-enums=[正则表达式]

如果未给出正则表达式,则跳过在 C 枚举中定义的所有常量。否则,仅跳过在名称与正则表达式匹配的枚举中定义的常量。

由于正则表达式是可选的,因此请确保如果省略正则表达式并且有一些待处理的参数(例如头文件名称),则此开关后至少跟随一个其他开关。这是可以的

h2xs -e -n Module::Foo foo.h

这是不行的

h2xs -n Module::Foo -e foo.h

在后者中,foo.h 被视为正则表达式

-f, --force

允许为头文件创建扩展,即使该头文件在标准包含目录中找不到。

-g, --global

在 .xs 文件中包含用于安全存储静态数据的代码。不使用静态数据的扩展可以忽略此选项。

-h, -?, --help

打印此 h2xs 的用法、帮助和版本,然后退出。

-k, --omit-const-func

对于声明为 const 的函数参数,在生成的 XS 代码中省略 const 属性。

-m, --gen-tied-var

实验性:对于在头文件中声明的每个变量,声明一个与 C 变量神奇绑定名称相同的 Perl 变量。

-n, --name=module_name

指定扩展的名称,例如:-n RPC::DCE

-o, --opaque-re=正则表达式

对于与正则表达式匹配的 C 类型,即使这些类型是 typedef 等效于类型映射中的类型,也使用“不透明”数据类型。不应在没有 -x 的情况下使用。

这可能很有用,因为例如,与整数 typedef 等效的类型可能代表与操作系统相关的句柄,并且可能希望以面向对象的方式使用这些句柄,例如 $handle->do_something()。如果要将所有 typedefed 类型处理为不透明类型,请使用 -o .

要匹配的类型将被清洗(除了逗号,逗号前面没有空格,以及多个 *,它们之间没有空格)。

-p, --remove-prefix=前缀

指定应从 Perl 函数名中删除的前缀,例如:-p sec_rgy_ 这将设置 XS PREFIX 关键字,并从通过 constant() 机制自动加载的函数中删除前缀。

-s, --const-subs=sub1,sub2

为指定的宏创建一个 Perl 子例程,而不是使用 constant() 子例程自动加载。假设这些宏的返回类型为 char *,例如:-s sec_rgy_wildcard_name,sec_rgy_wildcard_sid.

-t, --default-type=类型

指定 constant() 机制为宏使用的内部类型。默认值为 IV(带符号整数)。目前,在头文件扫描过程中找到的所有宏都将被假定为具有此类型。h2xs 的未来版本可能会获得进行有根据猜测的能力。

--use-new-tests

当存在--compat-version (-b) 时,生成的测试将使用Test::More 而不是TestTest 是 5.6.2 之前版本的默认值。Test::More 将被添加到生成的Makefile.PL 中的 PREREQ_PM 中。

--use-old-tests

将强制生成使用旧的Test 模块的测试代码。

--skip-exporter

不要使用Exporter 以及导出任何符号。

--skip-ppport

不要使用Devel::PPPort:无法移植到旧版本。

--skip-autoloader

不要使用模块AutoLoader;但保留常量() 函数和sub AUTOLOAD 用于常量。

--skip-strict

不要使用strict 编译指示。

--skip-warnings

不要使用warnings 编译指示。

-v, --version=version

为该扩展指定版本号。此版本号将添加到模板中。默认值为 0.01,如果指定了-B,则为 0.00_01。指定的版本应为数字。

-x, --autogen-xsubs

根据头文件中的函数声明自动生成 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

基于.h.c 文件的扩展

假设您有一些实现某些功能的 C 文件,以及相应的头文件。如何创建一个扩展,使这些功能在 Perl 中可用?以下示例假设头文件为 interface_simple.hinterface_hairy.h,并且您希望 Perl 模块命名为 Ext::Ension。如果您需要一些预处理器指令和/或与外部库的链接,请参阅 "OPTIONS" 中的标志 -F-L-l

查找目录名称

从 h2xs 的一个虚拟运行开始

h2xs -Afn Ext::Ension

此步骤的唯一目的是创建所需的目录,并让您知道这些目录的名称。从输出中您可以看到扩展的目录是 Ext/Ension

复制 C 文件

将您的头文件和 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 及其他人

另请参阅

perlperlxstutExtUtils::MakeMakerAutoLoader

诊断

如果无法读取或写入相关文件,则会显示通常的警告。

-x 的限制

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

有关更多详细信息,请参阅 perlxsperlxstut