是否可以添加“文本"?到 swig 中现有的类型图? [英] Is it possible to add "text" to an existing typemap in swig?

查看:21
本文介绍了是否可以添加“文本"?到 swig 中现有的类型图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了这个问题,但一个答案基本上是,你不会想要那样做:是否可以将代码添加到使用 Swig 为 C++ 代码构建 C# 包装器时的现有方法?

I found this question, but the one answer was basically, you wouldn't want to do that: Is it possible to add code to an existing method when using Swig to build a C# wrapper for C++ code?

在所描述的情况下,我实际上同意它,其中​​ OP 试图以一种可能脆弱的方式插入代码.就我而言,我正在按照答案建议的那样做:重命名方法并使用 %typemap(javacode) 来实现包装方法.

I actually agree with it in the case as described, where the OP was trying to insert code in a way that could be fragile. In my case I am doing exactly what the answer suggested: renaming the method and using %typemap(javacode) to implement the wrapping method.

但是我把它写成一个宏,我想覆盖几个方法,所以我最终调用了 %typecode(javacode) 多次,只有最后一个包装方法 javacode typemap 处于活动状态.

But I've written this as a macro, and I want to override several methods, so I end up calling %typecode(javacode) multiple times, and only the last wrapping method javacode typemap is active.

宏的细节很复杂,因为它使用变量args来表达签名.

The details of the macro are complicated, since it uses variable args to express the signature.

但是证明了这个问题:

%define WRAP(CLASS,METHOD)
%rename(method ## _internal,fullname=1) CLASS::METHOD;
%typemap(javamethodmodifiers) CLASS::METHOD "private";
%typemap(javacode) {
    public void METHOD() {
       METHOD ## _internal();  // delegate to original
       // extra code here
    }
}   // (note: dont use %{ %} -- need macro evaluation)
%enddef

WRAP(Foo,bar)
WRAP(Foo,baz)

class Foo {
   void bar();
   void baz();
}

只有 public void baz() { baz_internal();... } 被生成.这里的问题是 %rename 和 %typemap(javamethodmodifiers) 是唯一的,因为 CLASS::METHOD 的范围,但 %typemap(javacode) 适用于整个类.如果语法像

Only the public void baz() { baz_internal(); ... } gets generated. The problem here is that the %rename and %typemap(javamethodmodifiers) are unique since the scope to CLASS::METHOD, but the %typemap(javacode) applies to the whole class. If syntax like

 %typemap(javacode,append=true) {   // code   }

被支持,那么这将解决问题.有没有什么技术可以做到这一点?这对于像 javacode 或 javaimports 这样的默认值是空的类型映射是有意义的.

were supported, then this would solve the problem. Is there some technique that could accomplish this? This could make sense for typemaps like javacode or javaimports, whose defaults are empty.

推荐答案

我可以制作一个 SWIG 宏来生成您正在寻找的代码.这有点麻烦,但它有效.诀窍是滥用 javaout(使用 noblock=1)类型映射而不是 javacode,以便每个函数应用一次,而不是每个类应用一次:

I can make a SWIG macro that generates the code you're looking for. It's a bit of a bodge, but it works. The trick was abusing the javaout (with noblock=1) typemap instead of javacode so that it gets applied once per function rather than once per class:

%module test

%define WRAP(CLASS,METHOD)
%rename(METHOD ## _internal,fullname=1) CLASS::METHOD;
%javamethodmodifiers CLASS::METHOD "private";
%typemap(javaout,noblock=1) void CLASS::METHOD {
  {
    $jnicall;
  }

  public void METHOD() {
    METHOD ## _internal();
    // some other bits
  }
}
%enddef

WRAP(Foo,bar)
WRAP(Foo,baz)

class Foo {
public:
   void bar();
   void baz();
};

这将生成您正在寻找的代码,但我怀疑您可以完全跳过 %rename 并从 javaout 类型映射中完成所有操作.此方法适用于 SWIG 1.3 及更高版本.

This generates exactly the code you're looking for, but I suspect you could skip the %rename entirely and do it all from the javaout typemap. This approach works with SWIG 1.3 and upwards.

我确实尝试过使用 $typemap 的另一种方法并复制类型图,但最终没有成功.

I did try another approach with $typemap and copying typemaps around, but this didn't work out in the end.

如果你也想支持返回值的方法,你需要添加第三个宏参数:

If you want to support methods which return things too you'll want to add a third macro argument:

%define WRAP(CLASS,METHOD,RETURN)
%rename(METHOD ## _internal,fullname=1) CLASS::METHOD;
%javamethodmodifiers CLASS::METHOD "private";
%typemap(javaout,noblock=1) RETURN CLASS::METHOD {
    $typemap(javaout,RETURN)

  public $typemap(jstype,RETURN) METHOD() {
    RETURN result = METHOD ## _internal();
    // some other bits
    return result;
  }
}
%enddef

$typemap 用于引用默认的、不太专业的类型映射,以避免为非原始/特殊情况返回重复大量代码.

$typemap there is used to refer to the default, less specialised typemaps to avoid having to duplicate a lot of code for non-primitive/special case returns.

这篇关于是否可以添加“文本"?到 swig 中现有的类型图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆