@@ -10,6 +10,30 @@ use image::BGRImage;
1010use interface:: { Interface , RecognizeEnemyInput , WrappedPixels } ;
1111
1212use std:: ffi:: { c_char, c_int, c_void} ;
13+ use std:: panic;
14+
15+ /// Helper function to catch panics and log stack trace
16+ fn catch_panic < F , R > ( f : F ) -> Result < R , ( ) >
17+ where
18+ F : FnOnce ( ) -> R + panic:: UnwindSafe ,
19+ {
20+ panic:: catch_unwind ( f) . map_err ( |panic_info| {
21+ eprintln ! ( "Panic occurred in image-autowsgrs library:" ) ;
22+
23+ // Print panic message
24+ if let Some ( s) = panic_info. downcast_ref :: < & str > ( ) {
25+ eprintln ! ( "Panic message: {s}" ) ;
26+ } else if let Some ( s) = panic_info. downcast_ref :: < String > ( ) {
27+ eprintln ! ( "Panic message: {s}" ) ;
28+ } else {
29+ eprintln ! ( "Panic message: <unknown>" ) ;
30+ }
31+
32+ // Print backtrace if available
33+ eprintln ! ( "Stack backtrace:" ) ;
34+ eprintln ! ( "{}" , std:: backtrace:: Backtrace :: capture( ) ) ;
35+ } )
36+ }
1337
1438/// # Safety
1539/// The input pointer must be freed by caller
@@ -23,14 +47,17 @@ use std::ffi::{c_char, c_int, c_void};
2347/// e.g. [[0, 1], [2, 3], [4, 5]]
2448#[ no_mangle]
2549pub unsafe extern "C" fn locate ( input : * const c_void , output : * mut c_int ) -> c_int {
26- let image = BGRImage :: from_wrapped_pixels ( WrappedPixels :: from_raw ( input) ) ;
27- let result = locator:: locate ( & image) ;
28- if result. is_empty ( ) || result. len ( ) >= 32 {
29- return -1 ;
30- }
31- let len = result. len ( ) ;
32- output. copy_from_nonoverlapping ( result. as_ptr ( ) as * const c_int , len) ;
33- len as c_int
50+ catch_panic ( || {
51+ let image = BGRImage :: from_wrapped_pixels ( WrappedPixels :: from_raw ( input) ) ;
52+ let result = locator:: locate ( & image) ;
53+ if result. is_empty ( ) || result. len ( ) >= 32 {
54+ return -1 ;
55+ }
56+ let len = result. len ( ) ;
57+ output. copy_from_nonoverlapping ( result. as_ptr ( ) as * const c_int , len) ;
58+ len as c_int
59+ } )
60+ . unwrap_or ( -1 )
3461}
3562
3663/// # Safety
@@ -45,20 +72,23 @@ pub unsafe extern "C" fn locate(input: *const c_void, output: *mut c_int) -> c_i
4572/// e.g. "DD SS NO NO NO NO"
4673#[ no_mangle]
4774pub unsafe extern "C" fn recognize_enemy ( input : * const c_void , output : * mut c_char ) -> c_int {
48- let input = RecognizeEnemyInput :: from_raw ( input) ;
49- let result = recognize_enemy:: recognize_enemy (
50- & input. images ,
51- & recognize_enemy:: templates:: Template :: init_templates ( ) ,
52- ) ;
75+ catch_panic ( || {
76+ let input = RecognizeEnemyInput :: from_raw ( input) ;
77+ let result = recognize_enemy:: recognize_enemy (
78+ & input. images ,
79+ & recognize_enemy:: templates:: Template :: init_templates ( ) ,
80+ ) ;
5381
54- output. copy_from ( result. as_ptr ( ) as * const c_char , result. len ( ) ) ;
55- 0
82+ output. copy_from ( result. as_ptr ( ) as * const c_char , result. len ( ) ) ;
83+ 0
84+ } )
85+ . unwrap_or ( -1 )
5686}
5787
5888/// # Safety
5989/// The input pointer must be freed by caller
6090///
61- /// cant be failed, always return a character
91+ /// return '\0' if failed (panic occurred), otherwise return the recognized character
6292///
6393/// # Usage
6494///
@@ -67,7 +97,10 @@ pub unsafe extern "C" fn recognize_enemy(input: *const c_void, output: *mut c_ch
6797/// e.g. 'J'
6898#[ no_mangle]
6999pub unsafe extern "C" fn recognize_map ( input : * const c_void ) -> c_char {
70- let image = BGRImage :: from_wrapped_pixels ( WrappedPixels :: from_raw ( input) ) ;
71- let result = recognize_map:: recognize_map ( & image) ;
72- result as c_char
100+ catch_panic ( || {
101+ let image = BGRImage :: from_wrapped_pixels ( WrappedPixels :: from_raw ( input) ) ;
102+ let result = recognize_map:: recognize_map ( & image) ;
103+ result as c_char
104+ } )
105+ . unwrap_or_default ( )
73106}
0 commit comments