更改 shared_ptr 的 getCPtr() 可见性

Change getCPtr() visibility of a shared_ptr

我目前正在使用 swig 生成 Java 代码。

我有两个 swig 模块(module1module2),它们将创建两个包(fr.package1fr.package2)。 fr.package2 生成的 classes 需要使用其他包生成的 classes。为了实现这一点,我需要将 getCPtr() 方法的可见性更改为 public.

documentation中所写,我在我的接口文件中添加了:

SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)

module1 中,我也使用 shared_ptr 作为 class,像这样:

%module module1

%include <boost_shared_ptr.i>
%inline %{
    #include <boost/shared_ptr.hpp>
%}
%{
    #include "foo.h"
%}
SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
%shared_ptr(foo)
%include "foo.h"

当我 运行 swig 时,生成的 classes 对 getCPtr() 具有 public 可见性,除了 class foo.

为什么我使用 %shared_ptr 时它不起作用?使用 %shared_ptr 时,有没有办法将 getCPtr() 的可见性设置为 public?

我们需要解决的第一件事是为什么 shared_ptr 宏打破了这一点。答案在于 shared_ptr 宏本身的实际作用。简而言之,它提供了一堆额外的、专门的类型映射,包括提供 getCPtr 实现等的 javabody 类型映射。

这个答案的下一部分很快变成了关于类型映射匹配逻辑如何在 SWIG 中工作的讨论。如果您真的不在乎,可以放心地跳过它。

所以最初的问题是这里为 foo 提供的额外类型映射 "beat" SWIGTYPE 类型映射,因为它们更具体。 (SWIGTYPE 基本上是一个低优先级的通配符,代表任何没有更具体的类型)。这立即导致一个明显的想法:在两个修饰符控制宏中将 SWIGTYPE 更改为 foo。然而,那是行不通的,因为我们最终得到了两个相互竞争的 %typemap(javabody) foo 的供应。在那种情况下,最后看到的人获胜。因此,如果我们将界面更改为更像这样:

%shared_ptr(foo)
SWIG_JAVABODY_PROXY(public, public, foo)
SWIG_JAVABODY_TYPEWRAPPER(public, public, public, foo)

然后 public 的 javabody typemap 胜出。但这可能不是我们想要的,因为毕竟如果 shared_ptr 宏正在更改 javabody 类型映射,它可能这样做是有原因的,对吗?我们可以检查两者并查看,但我现在还没有真正这样做,因为无论如何都有更好的解决方案。

如果我们往里面看 boost_shared_ptr.i 就会发现有一种方法可以控制它也提供的 javabody 的修饰符。如果我们现在将模块设置为:

%module module1
#define SWIG_SHARED_PTR_TYPEMAPS(CONST, TYPE...) SWIG_SHARED_PTR_TYPEMAPS_IMPLEMENTATION(public, public, CONST, TYPE)

%include <boost_shared_ptr.i>

%shared_ptr(foo)

// ...

然后如你所愿。请注意,我们的 #define 在任何其他包含共享指针 header.

之前出现非常重要