0

我编写了一个 Ruby C++ 扩展来包装Google 的 re2 正则表达式库,但最近对该库的更新将函数的接口Match()从:

bool Match(const StringPiece& text,
           int startpos,
           Anchor anchor,
           StringPiece *match,
           int nmatch) const;

到:

bool Match(const StringPiece& text,
           int startpos,
           int endpos,
           Anchor anchor,
           StringPiece *match,
           int nmatch) const;

(注意新的int endpos论点。)

我的问题是:尽管 re2 似乎没有指定任何VERSION我可以自省的常量,我是否有可能在一个扩展中支持这个库的两个版本?

理想情况下,我希望能够尝试较新的版本(带有 6 个参数),如果失败,则回退到旧版本(因为我能够endpos轻松地回填参数)。

目前我的代码是这样的:

matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);

但如果你有旧版本的 re2,它需要是:

matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
4

2 回答 2

0

据我所知,你不能。这将要求您同时链接新旧版本的 RE2,这会使命名空间发生冲突。

除非存在与旧版本相似的此方法的版本,否则您将被新版本卡住。

如果您希望能够为这两个版本编译您的扩展,那么您必须修改您的编译步骤以定义一些您可以控制的标志。

#ifdef RE2_ODLFORMAT
matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
#else
matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
#endif

然后编译你的代码,你会按照这些思路做一些事情:

make RE2_OLDFORMAT=1 all # compile for old version
make all # default target is for new version
于 2012-02-27T12:48:11.910 回答
0

传统的答案是在安装时生成一个config.h或任何内容。

也就是说,在安装时你会检测安装的re2是哪个版本,然后config.h根据这个定义一个符号:

// config.h
#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED

#define RE2_MATCH_6_ARGS 1

#endif // CONFIG_H_INCLUDED

然后,你可以使用这个:

#if defined(RE2_MATCH_6_ARGS) && RE2_MATCH_6_ARGS == 1
  matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
#else
  matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
#endif

这是一个稳定的解决方案,应该可以很好地工作。


另一种可能性是破解系统...

Match在包装库中提供这两个函数的定义:

  • Match5抛出错误(请链接到 re2)
  • Match6转发给Match5.

问题是(在 Unix 世界中......),如果一个符号已经被加载,它不会被新定义覆盖。因此,只要re2首先加载,您就会陷入以下两种情况之一:

  • old re2:您的(包装器)库提供了一个定义,Match6该定义转发到re2提供的定义Match5
  • new re2:调用直接转到提供的Match6定义re2

多了。需要围绕re2. _ 不太可能使用静态链接(虽然从未尝试过......)。但不需要./configure一步。

于 2012-02-27T13:03:32.440 回答