2012-12-21 13 views
9

Próbuję użyć SWIG do zawinięcia klasy C++ do klasy Java. Ta klasa C++ ma metodę, która zgłasza wyjątek.Obsługa wyjątków C++ w Javie za pomocą SWIG

mam trzy cele, z których żadna nie są obecnie dzieje choć śledzę instrukcję jak rozumiem:

  • Aby uzyskać klasę Java, aby zadeklarować throws <exceptiontype> na metodzie, która rzuca się w C++
  • Aby uzyskać wygenerowaną przez SWIG klasę wyjątków rozszerzającą java.lang.Exception
  • Aby zastąpić Exception.getMessage() w wygenerowanej klasie SWIG.

Wygląda na to, że przyczyną problemu są moje typemap s, ponieważ żadna z powyższych sytuacji się nie dzieje. Co zrobiłem źle?

Minimalny przykład znajduje się poniżej. C++ nie musi się kompilować, interesuje mnie tylko wygenerowana Java. Klasa wyjątku jest nieistotna, a poniższy kod używa wyjątku IOException tylko dlatego, że używa go dokumentacja. Cały kod jest dostosowany z przykładów tutaj:

C++ plik nagłówka (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 plików:

%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(); 
    } 
%} 

Podczas pracy z swig -c++ -verbose -java test.i z SWIG 2.0.4, klasa wyjątków nie rozszerza java.lang.Exception i żadna z metod Java nie ma deklaracji throws.

Odpowiedz

9

Będziesz się kopał, kiedy to zobaczysz. Stała wersja interfejsu SWIG to:

%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" 

tj. %include "test.h" pochodzi od po mapach typów, które chcesz zastosować do klas w teście test.h, nie wcześniej. Pamięci typu SWIG powinny być widoczne w momencie, gdy klasy, do których się odnoszą, są widoczne.

+0

Jak niewiarygodnie frustrujące. Dzięki! –