add support for output string arguments
MODIFY
gen_rust.py
gen_rust.py
@@ -1695,19 +1695,55 @@ class StringTypeInfo(TypeInfo):
self.c_safe_id = "char_X"
self.rust_extern = "*mut c_char"
- def cpp_arg_func_call(self, var_name, is_output=False):
- return "{}({})".format(self.cpptype, var_name)
+ def is_output(self):
+ return self.is_by_ref and not self.is_const
+
+ def rust_arg_func_decl(self, var_name, is_output=False):
+ if self.is_output():
+ return "{}: &mut String".format(var_name)
+ return "{}: &str".format(var_name)
def rust_arg_pre_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "string_arg_output_send!(via {}_via)".format(var_name)
return "string_arg!({}{})".format("" if self.is_const else "mut ", var_name)
def rust_arg_func_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "&mut {}_via".format(var_name)
if self.is_const:
return "{}.as_ptr()".format(var_name)
return "{}.as_ptr() as _".format(var_name) # fixme: use as_mut_ptr() when it's stabilized
- def rust_arg_func_decl(self, var_name, is_output=False):
- return "{}: &str".format(var_name)
+ def rust_extern_arg_func_decl(self, var_name, is_output=False):
+ if self.is_output():
+ return "{}: *mut {}".format(var_name, self.rust_extern)
+ return super(StringTypeInfo, self).rust_extern_arg_func_decl(var_name, is_output)
+
+ def rust_arg_post_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "string_arg_output_receive!({}_via => {})".format(var_name, var_name)
+ return super(StringTypeInfo, self).rust_arg_post_call(var_name, is_output)
+
+ def cpp_arg_func_decl(self, var_name, is_output=False):
+ if self.is_output():
+ return "{}* {}".format(self.cpp_extern, var_name)
+ return super(StringTypeInfo, self).cpp_arg_func_decl(var_name, is_output)
+
+ def cpp_arg_pre_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "std::string {}_out".format(var_name)
+ return super(StringTypeInfo, self).cpp_arg_pre_call(var_name, is_output)
+
+ def cpp_arg_func_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "{}_out".format(var_name)
+ return "{}({})".format(self.cpptype, var_name)
+
+ def cpp_arg_post_call(self, var_name, is_output=False):
+ if self.is_output():
+ return "*{} = strdup({}_out.c_str())".format(var_name, var_name)
+ return super(StringTypeInfo, self).cpp_arg_post_call(var_name, is_output)
def cpp_method_return(self, is_constructor):
return "return { Error::Code::StsOk, NULL, strdup(ret.c_str()) };"

MODIFY
src/templ.rs
src/templ.rs
@@ -12,6 +12,18 @@ macro_rules! string_arg {
};
}
+macro_rules! string_arg_output_send {
+ (via $name_via: ident) => {
+ let mut $name_via = ::std::ptr::null_mut();
+ };
+}
+
+macro_rules! string_arg_output_receive {
+ ($name_via: ident => $name: ident) => {
+ *$name = $crate::templ::receive_string_mut($name_via);
+ };
+}
+
macro_rules! callback_arg {
($callback_name: ident($($tr_arg_name: ident: $tr_arg_type: ty),*) via $userdata_name: ident => ($($fw_arg_name: ident: $fw_arg_type: ty),*)) => {
::lazy_static::lazy_static!(

ADD
tests/objdetect.rs
+use std::path::PathBuf;
+
+use opencv::{
+ core::Mat,
+ imgcodecs,
+ objdetect,
+ types::VectorOfPoint,
+};
+
+#[test]
+fn qr_code() {
+ let qr_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/qr.png");
+
+ {
+ let mut detector = objdetect::QRCodeDetector::new().unwrap();
+ let src = imgcodecs::imread(qr_path.to_str().unwrap(), imgcodecs::IMREAD_COLOR).unwrap();
+ let mut pts = VectorOfPoint::new();
+ let mut straight = Mat::default();
+ let res = detector.detect_and_decode(&src, &mut pts, &mut straight).unwrap();
+ assert_eq!(res, "https://crates.io/crates/opencv");
+ assert_eq!(4, pts.len());
+ assert!(!straight.empty().unwrap());
+ }
+
+ {
+ let mut detector = objdetect::QRCodeDetector::new().unwrap();
+ let src = imgcodecs::imread(qr_path.to_str().unwrap(), imgcodecs::IMREAD_COLOR).unwrap();
+ let mut pts = VectorOfPoint::new();
+ let res = detector.detect(&src, &mut pts).unwrap();
+ assert!(res);
+ assert_eq!(4, pts.len());
+ let mut straight = Mat::default();
+ let res = detector.decode(&src, &pts, &mut straight).unwrap();
+ assert_eq!(res, "https://crates.io/crates/opencv");
+ assert!(!straight.empty().unwrap());
+ }
+
+ {
+ let src = imgcodecs::imread(qr_path.to_str().unwrap(), imgcodecs::IMREAD_COLOR).unwrap();
+ let mut pts = VectorOfPoint::new();
+ let res = objdetect::detect_qr_code(&src, &mut pts, 0.2, 0.1).unwrap();
+ assert!(res);
+ assert_eq!(4, pts.len());
+ let mut out = String::new();
+ let mut straight = Mat::default();
+ let res = objdetect::decode_qr_code(&src, &pts, &mut out, &mut straight).unwrap();
+ assert!(res);
+ assert_eq!(out, "https://crates.io/crates/opencv");
+ assert!(!straight.empty().unwrap());
+ }
+}

ADD
tests/qr.png
tests/qr.png
Binary files /dev/null and b/tests/qr.png differ

add support for output string arguments