gpt4 book ai didi

java - 实例化模板和 SWIG

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:09:26 24 4
gpt4 key购买 nike

我有以下问题,我不知道如何解决。我想使用 SWIG 为同一文件中的这两个类创建一个 Java 包装器:

utilities.h:

template<class T>
class EncoderInterface
{
public:
virtual ~EncoderInterface()
{
}
virtual const cdap_rib::SerializedObject* encode(const T &object) = 0;
virtual T* decode(
const cdap_rib::SerializedObject &serialized_object) const = 0;
};

class IntEncoder : public rib::EncoderInterface<int>
{
public:
const cdap_rib::SerializedObject* encode(const int &object);
int* decode(const cdap_rib::SerializedObject &serialized_object) const;
};

然后我在 .i 中做通常的痛饮:

%{
#include "utilities.h"
%}

%include "utilities.h"

它说:

Warning 401: Nothing known about base class 'EncoderInterface< int >'. Ignored.
Warning 401: Maybe you forgot to instantiate 'EncoderInterface< int >' using %template.

如果我尝试像这样使用 %template 东西:

%template(IntEncoder) EncoderInterface<int>;

Warning 302: Identifier 'IntEncoder' redefined (ignored) (Renamed from 'EncoderInterface< int >'),
utilities.h:302: Warning 302: previous definition of 'IntEncoder'.

IntEncoderutilities.cc 中有代码,我想让实用程序的用户创建新的模板实例,或者如果他愿意,可以使用给定的实例。我真的不想更改 IntEncoder 的名称,因此库的任何用户(来自 C++ 或 Java)都将使用相同的名称。

我读过一些关于拆分文件的内容(在一个文件中保留 EncoderInterface 模板,在另一个文件中保留实例化)这是解决这个问题的唯一方法吗?如果可以避免,我不想创建新文件。

最佳答案

Warning 401: Nothing known about base class 'EncoderInterface< int >'. Ignored.
Warning 401: Maybe you forgot to instantiate 'EncoderInterface< int >' using %template.

EncoderInterface<int>IntEncoder 的基类. SWIG 正在尝试结束您的 IntEncoder Java 的类,但它没有这个基类的包装器,因为它只包装模板的实例化。

在为模板基类指定 SWIG 名称之前,它不知道如何为 IntEncoder 制作 Java 包装器派生自 EncoderInterface<int> 周围的包装器,这就是它发出警告的原因。

If I try to use the %template thing like this:

%template(IntEncoder) EncoderInterface<int>;

Warning 302: Identifier 'IntEncoder' redefined (ignored) (Renamed from 'EncoderInterface< int >'),
utilities.h:302: Warning 302: previous definition of 'IntEncoder'.

这是正确的想法,但您现在已经告诉 SWIG 在 EncoderInterface<int> 附近调用包装器和你的其他类(class)一样,IntEncoder .

您需要告诉 SWIG 在 EncoderInterface<int> 附近调用包装器别的东西,例如IntEncoderInterface :

%template(IntEncoderInterface) EncoderInterface<int>;

您可以随心所欲地调用它,只要它是您喜欢的名称作为 Java API 中的类名即可。

您只能使用 SWIG 包装 C++ 模板的实例化,您不能,例如,将它们包装为 Java 泛型类。

如果您需要 EncoderInterface<T> 的实例化对于不同类型 T同样,您必须添加 %template声明每种类型,告诉 SWIG 在 Java 中用不同的类名包装它们中的每一种。

如果为 EncoderInterface 自动生成 Java 包装器使用 Java 泛型的是您真正想要的,那么您就不走运了。如果您需要您的 Java API 与您的 C++ API 保持一致,您将不得不探索其他 API 样式(我可以看到这是某种序列化接口(interface),但不知道您想要序列化的类型的详细信息API,以及基类中支持的功能,但我不能建议任何具体的替代策略。

I have read something about splitting files (keeping EncoderInterface template in one file and the instantiation in another one) is this the only solution to this problem? I don't want to create new files if I can avoid it.

您阅读的内容可能暗示为了对 SWIG 隐藏模板,这样它就不会看到它或尝试包装它。如果您根本不想包装基类,这是一个选项。

虽然您不需要将它放在另一个文件中,但您可以使用预处理器隐藏它(请注意,IntEncoderEncoderInterface<int> 的继承在此处对 SWIG 隐藏,除了 EncoderInterface 本身) :

#ifndef SWIG
template<class T>
class EncoderInterface
{
public:
virtual ~EncoderInterface()
{
}
virtual const cdap_rib::SerializedObject* encode(const T &object) = 0;
virtual T* decode(
const cdap_rib::SerializedObject &serialized_object) const = 0;
};
#endif

class IntEncoder
#ifndef SWIG
: public EncoderInterface<int>
#endif
{
public:
const cdap_rib::SerializedObject* encode(const int &object);
int* decode(const cdap_rib::SerializedObject &serialized_object) const;
};

另请注意,原样,int* decode 的返回类型方法将被包装为不友好的 SWIGTYPE_p_int ,这可能不是您想要的。也许decode可以按值 ( int ) 返回,它将直接包装为 int在 Java 中。

关于java - 实例化模板和 SWIG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29343685/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com