diff --git a/gtwrap/matlab_wrapper/templates.py b/gtwrap/matlab_wrapper/templates.py index c1c7e75..bff1650 100644 --- a/gtwrap/matlab_wrapper/templates.py +++ b/gtwrap/matlab_wrapper/templates.py @@ -137,6 +137,7 @@ class WrapperTemplate: switch(id) {{ {cases} }} }} catch(const std::exception& e) {{ + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\\n" + std::string(e.what()) + "\\n").c_str()); }}\n std::cout.rdbuf(outbuf); diff --git a/matlab.h b/matlab.h index 37dffe4..1347f29 100644 --- a/matlab.h +++ b/matlab.h @@ -33,9 +33,7 @@ using gtsam::Matrix; using gtsam::Point2; using gtsam::Point3; -extern "C" { #include -} #include #include diff --git a/tests/expected/matlab/class_wrapper.cpp b/tests/expected/matlab/class_wrapper.cpp index fb7499d..29d7156 100644 --- a/tests/expected/matlab/class_wrapper.cpp +++ b/tests/expected/matlab/class_wrapper.cpp @@ -1380,6 +1380,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/enum_wrapper.cpp b/tests/expected/matlab/enum_wrapper.cpp index 637dd50..71e8075 100644 --- a/tests/expected/matlab/enum_wrapper.cpp +++ b/tests/expected/matlab/enum_wrapper.cpp @@ -315,6 +315,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/functions_wrapper.cpp b/tests/expected/matlab/functions_wrapper.cpp index 7ec9638..e076237 100644 --- a/tests/expected/matlab/functions_wrapper.cpp +++ b/tests/expected/matlab/functions_wrapper.cpp @@ -402,6 +402,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/geometry_wrapper.cpp b/tests/expected/matlab/geometry_wrapper.cpp index afb2880..691fddb 100644 --- a/tests/expected/matlab/geometry_wrapper.cpp +++ b/tests/expected/matlab/geometry_wrapper.cpp @@ -400,6 +400,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/inheritance_wrapper.cpp b/tests/expected/matlab/inheritance_wrapper.cpp index ab0da2e..cc82eda 100644 --- a/tests/expected/matlab/inheritance_wrapper.cpp +++ b/tests/expected/matlab/inheritance_wrapper.cpp @@ -995,6 +995,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/multiple_files_wrapper.cpp b/tests/expected/matlab/multiple_files_wrapper.cpp index 548fd2a..00e141a 100644 --- a/tests/expected/matlab/multiple_files_wrapper.cpp +++ b/tests/expected/matlab/multiple_files_wrapper.cpp @@ -218,6 +218,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/namespaces_wrapper.cpp b/tests/expected/matlab/namespaces_wrapper.cpp index 9c4be9e..2e327ec 100644 --- a/tests/expected/matlab/namespaces_wrapper.cpp +++ b/tests/expected/matlab/namespaces_wrapper.cpp @@ -538,6 +538,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/special_cases_wrapper.cpp b/tests/expected/matlab/special_cases_wrapper.cpp index ec8bb1b..1cc8579 100644 --- a/tests/expected/matlab/special_cases_wrapper.cpp +++ b/tests/expected/matlab/special_cases_wrapper.cpp @@ -268,6 +268,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/expected/matlab/template_wrapper.cpp b/tests/expected/matlab/template_wrapper.cpp index a65fdc9..057e26f 100644 --- a/tests/expected/matlab/template_wrapper.cpp +++ b/tests/expected/matlab/template_wrapper.cpp @@ -214,6 +214,7 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) break; } } catch(const std::exception& e) { + std::cout.rdbuf(outbuf); mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str()); } diff --git a/tests/test_matlab_wrapper.py b/tests/test_matlab_wrapper.py index 35e243d..f30da07 100644 --- a/tests/test_matlab_wrapper.py +++ b/tests/test_matlab_wrapper.py @@ -480,6 +480,34 @@ def test_deconstructors_are_idempotent(self): ' }\n' ' delete self;', cpp_content) + def test_mex_error_path_restores_stream(self): + """MEX failures restore std::cout before leaving the gateway.""" + file = osp.join(self.INTERFACE_DIR, 'functions.i') + wrapper = MatlabWrapper( + module_name='functions', + top_module_namespace=['gtsam'], + ignore_classes=[''], + ) + wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR) + + cpp_file = osp.join(self.MATLAB_ACTUAL_DIR, + 'functions_wrapper.cpp') + with open(cpp_file, 'r', encoding='UTF-8') as generated_file: + cpp_content = generated_file.read() + + self.assertIn( + '} catch(const std::exception& e) {\n' + ' std::cout.rdbuf(outbuf);\n' + ' mexErrMsgTxt(', cpp_content) + + matlab_header = osp.join(self.TEST_DIR, '..', 'matlab.h') + with open(matlab_header, 'r', encoding='UTF-8') as header_file: + header_content = header_file.read() + + self.assertIn('#include ', header_content) + self.assertNotIn('extern "C" {\n#include \n}', + header_content) + def test_size_t_round_trip(self): """Generated size_t wrappers use alias-safe scalar conversions.""" file = osp.join(self.INTERFACE_DIR, 'matlab_integer_aliases.i')