草庐IT

java - 实例化模板和 SWIG

coder 2024-02-23 原文

我有以下问题,我不知道如何解决。 我想使用 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/

有关java - 实例化模板和 SWIG的更多相关文章

  1. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  2. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  6. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐