Fix using exception in modules importing other modules
Ensure that we have only a single SWIG_CException_Raise() function across all modules instead of having per-module functions and, worse, per-module PendingException variables, which resulted in compile-time errors and couldn't work anyhow because function checking for the current exception didn't necessarily use the same "global" variable where it was stored. More formally, old version resulted in ODR violations and undefined behaviour. The way we avoid it now is rather ugly and consists in excluding SWIG_CException from wrapping using the hack in the source code which postpones wrapping this class until the very end and checks if we had encountered any %import directives and simply doesn't wrap it if we did. The same code is used to define the special SWIG_CException_DEFINED preprocessor symbol which is then used in the generated code to prevent the SWIG_CException class declaration from being compiled as part of the wrapper too (because this still happens due to %inline being used for its definition, and there doesn't seem to be any better way to avoid this). This is definitely not pretty, but at least adding "throw(char*)" to a couple of functions in mod_[ab].i test suite files works now instead of failing (even without linking and running) as before. This commit doesn't modify the test suite to avoid possible problems with the other languages, however.
This commit is contained in:
parent
9a8ebbb998
commit
727a65c0e8
2 changed files with 50 additions and 2 deletions
|
|
@ -11,7 +11,14 @@
|
|||
extern "C" void SWIG_CException_Raise(int code, const char* msg);
|
||||
%}
|
||||
|
||||
// This class is special too because its name is used in c.cxx source. It is
|
||||
// only defined if the code there didn't predefine SWIG_CException_DEFINED
|
||||
// because the class is already defined in another module.
|
||||
//
|
||||
// It has to be seen by SWIG because we want to generate wrappers for its
|
||||
// public functions to be able to use it from the application code.
|
||||
%inline %{
|
||||
#ifndef SWIG_CException_DEFINED
|
||||
class SWIG_CException {
|
||||
public:
|
||||
SWIG_CException(const SWIG_CException& ex) throw() : code(ex.code), msg(strdup(ex.msg)) { }
|
||||
|
|
@ -40,16 +47,19 @@ private:
|
|||
|
||||
SWIG_CException& operator=(const SWIG_CException& ex);
|
||||
};
|
||||
#endif // SWIG_CException_DEFINED
|
||||
%}
|
||||
|
||||
// This part is implementation only and doesn't need to be seen by SWIG.
|
||||
%{
|
||||
#ifndef SWIG_CException_DEFINED
|
||||
SWIG_CException *SWIG_CException::PendingException = 0;
|
||||
|
||||
SWIGEXPORTC void SWIG_CException_Raise(int code, const char* msg) {
|
||||
delete SWIG_CException::PendingException;
|
||||
SWIG_CException::PendingException = new SWIG_CException(code, msg);
|
||||
}
|
||||
#endif // SWIG_CException_DEFINED
|
||||
%}
|
||||
|
||||
%insert("runtime") "swigerrors.swg"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue