java - 以编程方式切换 API 命名约定

标签 java c++ vim naming-conventions swig

背景

FreeLing API 定义了一个不遵守标准 Java 命名约定的接口(interface)。例如:

package freeling;

public class sentence extends ListWord {
  public void set_parse_tree(parse_tree arg0) {

接口(interface)是使用SWIG定义的,类似于 IDL :

class sentence : public std::list<word> {
 public:
  sentence(void);

  void set_parse_tree(const parse_tree &);

问题

从学术上讲,您如何将接口(interface)映射到传统的 Java 命名标准(例如,class SentencesetParseTree( parseTree arg0 ))?

想法

  1. 转换 650+ 行 interface file手动(并向开发人员发送补丁)。
  2. 正则表达式 search and replace voodoo(使用 vi)::1,$s/_\([a-z]\)/\u\1/g
  3. 从 53 个自动生成的 Java 源文件创建包装器类。

谢谢!

最佳答案

SWIG 提供了一个 %rename 指令,允许在客户端和实现语言中使用不同的名称。 但这样做会使接口(interface)文件的长度增加近一倍。

实际上,SWIG 提供了批量重命名。参见 the documentation

5.4.7.2 Advanced renaming support

While writing %rename for specific declarations is simple enough, sometimes the same renaming rule needs to be applied to many, maybe all, identifiers in the SWIG input. For example, it may be necessary to apply some transformation to all the names in the target language to better follow its naming conventions, like adding a specific prefix to all wrapped functions. Doing it individually for each function is impractical so SWIG supports applying a renaming rule to all declarations if the name of the identifier to be renamed is not specified:

%rename("myprefix_%s") ""; // print -> myprefix_print

This also shows that the argument of %rename doesn't have to be a literal string but can be a printf()-like format string. In the simplest form, "%s" is replaced with the name of the original declaration, as shown above. However this is not always enough and SWIG provides extensions to the usual format string syntax to allow applying a (SWIG-defined) function to the argument. For example, to wrap all C functions do_something_long() as more Java-like doSomethingLong() you can use the "lowercamelcase" extended format specifier like this:

%rename("%(lowercamelcase)s") ""; // foo_bar -> fooBar; FooBar -> fooBar

Some functions can be parametrized, for example the "strip" one strips the provided prefix from its argument. The prefix is specified as part of the format string, following a colon after the function name:

%rename("%(strip:[wx])s") ""; // wxHello -> Hello; FooBar -> FooBar

我的建议是保持原样。您正在调用 C++ 函数,它们具有 C++ 名称。如果有的话,这可以帮助您记住您正在调用 C++ 并且需要遵循 C++ 对象生命周期管理规则,JNI 性能会受到轻微影响,等等。

关于java - 以编程方式切换 API 命名约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10790795/

相关文章:

java - 如何在 Spring boot 中使用 JCS(Rest api)

c++ - STL vector 上的奇怪复制构造函数错误

c++ - Visual Studio 中的 wxWidgets 链接问题

vim - 是否可以将外部命令的输出传递给 `:tabnew` ?

vim - 如何在Vim的自动完成系统中预览第一个单词?

java - 我可以让 H2 在内存数据库中自动创建模式吗?

java - 尝试使用 hibernate 4 测试记录的存在

c++ - 如何在 C++ 数据结构中存储 Fortran 风格的长字符标量

php - 关闭字符串中的 php 标记会停止语法突出显示

java - 如何测试数据库连接是否成功关闭?