2012-12-21 10 views
9

Sto tentando di utilizzare SWIG per racchiudere una classe C++ in una classe Java. Questa classe C++ ha un metodo che genera un'eccezione.Gestione delle eccezioni C++ in Java tramite SWIG

Ho tre obiettivi, nessuno dei quali è attualmente accadendo, anche se ho seguito il manuale di se ho capito bene:

  • Per ottenere la classe Java per dichiarare throws <exceptiontype> sul metodo che genera in C++
  • Per ottenere la classe Exception generata da SWIG per estendere java.lang.Exception
  • Per ignorare Exception.getMessage() nella classe SWIG generata.

Sembra che la radice del problema sembra che i miei typemap s non vengano applicati, poiché non si verifica nulla di quanto sopra. Cosa ho fatto di sbagliato?

L'esempio minimo è di seguito. Il C++ non deve essere compilato, mi interessa solo il Java generato. La classe dell'eccezione è irrilevante e il codice seguente utilizza IOException solo perché la documentazione lo utilizza. Tutto il codice è adattato dagli esempi qui:

C++ file di intestazione (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 lima .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(); 
    } 
%} 

Quando si esegue questo con swig -c++ -verbose -java test.i con SWIG 2.0.4, la classe di eccezione non si estende java.lang.Exception e nessuno dei metodi Java ha una dichiarazione throws.

risposta

9

Ti prenderai a calci quando lo vedrai. Una versione fissa dell'interfaccia 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" 

I.e. %include "test.h" viene dopo i typemap che si desidera applicare alle classi in test.h, non prima. Le typemap devono essere state viste da SWIG nel momento in cui le classi a cui si applicano vengono viste per la prima volta.

+0

Quanto incredibilmente frustrante. Grazie! –