我没有用过 SWIG,所以我不能直接和它说话。但我对Inline ::CPP非常熟悉。
如果您想编写可以在 Perl 中编译并变得可调用的 C++ 代码,Inline::CPP 可以帮助您实现这一点。只要 C++ 代码不变,它就应该只编译一次。如果您基于 Inline::CPP 构建模块,则代码将在模块安装时编译,因此其他用户永远不会真正看到第一次编译滞后;它发生在安装时,就在测试阶段之前。
Inline::CPP 并非 100% 没有可移植性问题。目标用户必须拥有与用于构建 Perl 的 C 编译器类似的 C++ 编译器,并且 C++ 标准库的版本应该能够生成与 Perl 兼容的二进制代码。Inline::CPP 使用 CPAN 测试仪的成功率约为 94%。而最后的 6% 几乎总是归结为安装过程中没有正确解读要使用的 C++ 编译器和库的问题。......其中,它通常归结为图书馆。
假设您作为模块作者发现自己属于 95% 的人,他们在安装 Inline::CPP 时没有问题。如果您知道您的目标受众将属于同一类别,那么基于 Inline::CPP 生成一个模块很简单。您基本上必须添加几个指令(VERSION 和 NAME),并将 Makefile.PL 的 ExtUtils::MakeMaker 调用换成 Inline::MakeMaker(它将调用 ExtUtils::MakeMaker)。您可能还需要一个 CONFIGURE_REQUIRES 指令来指定 ExtUtils::MakeMaker 在创建发行版时的当前版本;这可确保您的用户拥有更干净的安装体验。
现在,如果您正在创建用于一般消费的模块并且不知道您的目标用户是否适合可以使用 Inline::CPP 的 94% 的大多数用户,那么您最好删除 Inline::CPP 依赖项。无论如何,您可能希望这样做只是为了最小化依赖链;它对您的用户更好。在这种情况下,编写代码以使用 Inline::CPP,然后使用 InlineX::CPP2XS 将其转换为普通的旧 XS 模块。您的用户现在无需先拉入 Inline::CPP 即可进行安装。
C++ 是一门大型语言,Inline::CPP 处理其中很大一部分。注意类型映射文件,以确定可以自动传递(和转换)哪些类型的参数,以及使用“guts and API”调用更好地处理哪些类型。我不推荐使用的一项功能是自动字符串转换,因为它会产生对 Unicode 不友好的转换。更好地通过 API 调用显式处理字符串。
没有被 Inline::CPP 优雅处理的 C++ 部分是模板元编程。您可以在代码中自由使用模板,也可以自由使用 STL。但是,您不能简单地传递 STL 类型参数并希望 Inline::CPP 知道如何转换它们。它处理 POD(基本数据类型),而不是 STL 的东西。此外,如果您编写基于模板的函数或对象方法,C++ 编译器将不知道 Perl 计划在什么上下文中调用该函数,因此它不知道在编译时将什么类型应用于模板。因此,直接暴露给 Inline::CPP 的函数和对象方法需要是普通函数或方法;不是模板函数或类。
只要您知道会发生什么,这些限制在实践中并不难处理。如果您想将模板类直接暴露给 Inline::CPP,只需编写一个包装类,它可以继承或组合模板类的自身,但为其提供一个具体类型供 Inline::CPP 使用。
Inline::CPP 在为现有 C++ 库自动生成函数包装器时也很有用。该文档解释了如何做到这一点。
与 Swig相比,Inline::CPP 的优势之一是,如果您已经对perlguts、perlapi和perlcall有一定的经验,那么您就会有宾至如归的感觉。使用 Swig,您必须首先学习 Swig 的做事方式,然后弄清楚如何将其应用到 Perl,以及如何以 CPAN 可分发的方式进行操作。
使用 Inline::CPP 的另一个优点是它在 Perl 社区中有点熟悉。你会发现了解 Perl XS、Inline::C 以及在某种程度上了解 Inline::CPP 的人比使用 Swig 和 Perl 的人要多得多。尽管 XS 可能会很混乱,但它比使用 Perl 和 Swig 走得更远。
Inline::CPP 也是inline@perl.org邮件列表中的一个常见主题。除了我自己之外,Inline::C 的维护者和其他几位 Inline 家族的维护者也经常出现在这个列表中,并尽最大努力帮助需要帮助的人使用 Inline 模块家族。
您可能还会发现我在 Inline::CPP 上的 Perl Mongers 演讲有助于探索它如何为您工作。此外,Math::Prime::FastSieve作为基于 Inline::CPP(具有 Inline::CPP 依赖项)的模块的概念验证。此外,当前的 Inline 维护者和 InlineX::CPP2XS 的作者 Rob (sisyphus) 实际上在InlineX::CPP2XS发行版中包含了一个示例,该示例采用我的 Math::Prime::FastSieve 并使用他的内联X::CPP2XS。