通过 SWIG 处理 Java 中的 C++ 异常

Posted

技术标签:

【中文标题】通过 SWIG 处理 Java 中的 C++ 异常【英文标题】:Handling C++ exceptions in Java via SWIG 【发布时间】:2012-12-21 16:29:33 【问题描述】:

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

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

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

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

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

http://www.swig.org/Doc1.3/Java.html#typemap_attributes http://www.swig.org/Doc1.3/Java.html#exception_typemap

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 声明。

【问题讨论】:

【参考方案1】:

当你看到这个时,你会踢自己。 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 需要在它们应用的类第一次看到类型图时看到它们。

【讨论】:

多么令人沮丧。谢谢!

以上是关于通过 SWIG 处理 Java 中的 C++ 异常的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 反弹的对象的 SWIG Java 保留类信息

通过 SWIG 链接 C++ 和 Java GUI

在 try catch 中包装所有 swig 生成的方法

如何在 Python 中处理 SWIG 导向器方法中的 void 指针

SWIG C++ TCL:处理内存中预先存在的对象

SWIG (Java):如何将带有回调函数的结构从 Android 应用程序传递给 C++?