9

我正在尝试使用 SWIG 将 C++ 类包装到 Java 类中。这个 C++ 类有一个引发异常的方法。

我有三个目标,尽管我按照我的理解遵循了手册,但目前都没有实现:

  • 让 Java 类throws <exceptiontype>在 C++ 中抛出的方法上声明
  • 让 SWIG 生成的异常类扩展java.lang.Exception
  • Exception.getMessage()在生成的 SWIG 类中覆盖。

似乎问题的根源似乎是 my typemaps 没有被应用,因为以上都没有发生。我做错了什么?

最小的例子如下。C++ 不必编译,我只对生成的 Java 感兴趣。异常的类别无关紧要,下面的代码使用 IOException 只是因为文档使用它。所有代码均改编自此处的示例:

C++ 头文件(test.h):

#include <string>

class CustomException {
private:
  std::string message;
public:
  CustomException(const std::string& message) : message(msg) {}
  ~CustomException() {}
  std::string what() {
    return message;
  }
};

class Test {
public:
  Test() {}
  ~Test() {}
  void something() throw(CustomException) {};
};

SWIG .i 文件:

%module TestModule
%{
#include "test.h"
%}

%include "std_string.i" // for std::string typemaps
%include "test.h"

// Allow C++ exceptions to be handled in Java
%typemap(throws, throws="java.io.IOException") CustomException {
  jclass excep = jenv->FindClass("java/io/IOException");
  if (excep)
    jenv->ThrowNew(excep, $1.what());
  return $null;
}

// Force the CustomException Java class to extend java.lang.Exception
%typemap(javabase) CustomException "java.lang.Exception";

// Override getMessage()
%typemap(javacode) CustomException %{
  public String getMessage() {
    return what();
  }
%}

使用 SWIG 2.0.4运行它时swig -c++ -verbose -java test.i,异常类不会扩展java.lang.Exception,并且所有 Java 方法都没有throws声明。

4

1 回答 1

10

当你看到这个时,你会踢自己。SWIG 界面的固定版本是:

%module TestModule
%{
#include "test.h"
%}

%include "std_string.i" // for std::string typemaps

// Allow C++ exceptions to be handled in Java
%typemap(throws, throws="java.io.IOException") CustomException {
  jclass excep = jenv->FindClass("java/io/IOException");
  if (excep)
    jenv->ThrowNew(excep, $1.what());
  return $null;
}

// Force the CustomException Java class to extend java.lang.Exception
%typemap(javabase) CustomException "java.lang.Exception";

// Override getMessage()
%typemap(javacode) CustomException %{
  public String getMessage() {
    return what();
  }
%}

%include "test.h"

%include "test.h"出现您希望应用于 test.h 中的类的类型映射之后,而不是之前。SWIG 需要在首次看到它们应用的类时看到类型图。

于 2012-12-23T11:43:18.833 回答