实例化模板和 SWIG
Instantiated templates and SWIG
我有以下问题,我不知道如何解决。
我想使用 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'.
IntEncoder
在 utilities.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
的基数 class。 SWIG 正在尝试为 Java 包装您的 IntEncoder
class,但它没有针对此基础 class 的包装器,因为它只包装模板的实例化。
直到 SWIG 为模板基础 class 指定了一个名称,它才知道如何使 IntEncoder
的 Java 包装器派生自 [=14] 的包装器=],这就是它发出警告的原因。
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
.[=40= 相同的东西]
您需要告诉 SWIG 在 EncoderInterface<int>
周围调用包装器,例如IntEncoderInterface
:
%template(IntEncoderInterface) EncoderInterface<int>;
你可以随心所欲地称呼它,只要它是你喜欢的名字作为你 Java API 中 class 的名字即可。
您只能使用 SWIG 封装 C++ 模板的实例化,您不能,例如,将它们封装为 Java 泛型 classes .
如果您还需要为不同类型 T
实例化 EncoderInterface<T>
,则必须为每个类型添加一个 %template
声明,告诉 SWIG 结束他们每个人在 Java.
中都有不同的 class 名字
如果使用 Java 泛型的 EncoderInterface
自动生成的 Java 包装器是您真正想要的,那您就倒霉了。如果您需要 Java API 与您的 C++ API 保持一致,您将不得不探索其他 API 样式(我可以看到这是某种序列化接口,但不知道要用 API 序列化的类型的详细信息,以及基础 class 中支持的功能,但我无法建议任何具体的替代策略)。
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 隐藏模板,这样它就不会看到它或尝试包装它。这是一个选项,如果你根本不想包装基础 class。
虽然你不需要把它放在另一个文件中,你可以使用预处理器隐藏它(注意 IntEncoder
从 EncoderInterface<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;
};
另请注意,您的 decode
方法中的 int*
return 类型将被包装为不友好的 SWIGTYPE_p_int
,这可能不是您想要的想。也许 decode
可以 return 按值 (int
) 相反,它将直接包装为 int
in Java.
我有以下问题,我不知道如何解决。 我想使用 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'.
IntEncoder
在 utilities.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
的基数 class。 SWIG 正在尝试为 Java 包装您的 IntEncoder
class,但它没有针对此基础 class 的包装器,因为它只包装模板的实例化。
直到 SWIG 为模板基础 class 指定了一个名称,它才知道如何使 IntEncoder
的 Java 包装器派生自 [=14] 的包装器=],这就是它发出警告的原因。
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
.[=40= 相同的东西]
您需要告诉 SWIG 在 EncoderInterface<int>
周围调用包装器,例如IntEncoderInterface
:
%template(IntEncoderInterface) EncoderInterface<int>;
你可以随心所欲地称呼它,只要它是你喜欢的名字作为你 Java API 中 class 的名字即可。
您只能使用 SWIG 封装 C++ 模板的实例化,您不能,例如,将它们封装为 Java 泛型 classes .
如果您还需要为不同类型 T
实例化 EncoderInterface<T>
,则必须为每个类型添加一个 %template
声明,告诉 SWIG 结束他们每个人在 Java.
如果使用 Java 泛型的 EncoderInterface
自动生成的 Java 包装器是您真正想要的,那您就倒霉了。如果您需要 Java API 与您的 C++ API 保持一致,您将不得不探索其他 API 样式(我可以看到这是某种序列化接口,但不知道要用 API 序列化的类型的详细信息,以及基础 class 中支持的功能,但我无法建议任何具体的替代策略)。
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 隐藏模板,这样它就不会看到它或尝试包装它。这是一个选项,如果你根本不想包装基础 class。
虽然你不需要把它放在另一个文件中,你可以使用预处理器隐藏它(注意 IntEncoder
从 EncoderInterface<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;
};
另请注意,您的 decode
方法中的 int*
return 类型将被包装为不友好的 SWIGTYPE_p_int
,这可能不是您想要的想。也许 decode
可以 return 按值 (int
) 相反,它将直接包装为 int
in Java.