Sort out generation of string return type wrappers
MODIFY
binding-generator/src/type_ref.rs
binding-generator/src/type_ref.rs
@@ -1298,7 +1298,7 @@ impl<'tu, 'g> TypeRef<'tu, 'g> {
if !self.is_generic() && !self.is_void() {
out.push(Box::new(if self.is_string() {
let type_ref = TypeRef::new(
- self.gen_env.resolve_type("const char*").expect("Can't resolve const char*"),
+ self.gen_env.resolve_type(&self.cpp_extern_return()).expect("Can't resolve string cpp_extern_return()"),
self.gen_env,
);
let def_location = match def_location {

MODIFY
binding-generator/src/vector.rs
binding-generator/src/vector.rs
@@ -55,13 +55,38 @@ impl<'tu, 'g> Vector<'tu, 'g> {
pub fn dependent_types(&self) -> Vec<Box<dyn GeneratedElement + 'g>> {
let element_type = self.element_type();
- let needs_ioa = self.is_data_type(&element_type);
- let needs_char_ptr = element_type.is_string();
+ let is_data_type = self.is_data_type(&element_type);
let mut out = element_type.dependent_types_with_mode(DependentTypeMode::ForReturn(DefinitionLocation::Type));
- out.reserve(2 + if needs_ioa { 3 } else { 0 } + if needs_char_ptr { 1 } else { 0 });
+ out.reserve(2 + if is_data_type { 3 } else { 0 });
+ if element_type.is_string() {
+ out.push(Box::new(ReturnTypeWrapper::new(
+ TypeRef::new(self.gen_env.resolve_type(&element_type.cpp_extern_return()).expect("Can't resolve string cpp_extern_return()"), self.gen_env),
+ self.gen_env,
+ DefinitionLocation::Custom(element_type.rust_module().into_owned()),
+ )));
+ // We need to generate return wrappers for std::vector<cv::String>, but it has several issues:
+ // * we can't use get_canonical_type() because it resolves into compiler dependent inner type like
+ // std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>
+ // * we can't generate both vector<cv::String> and vector<std::string> because for OpenCV 4
+ // cv::String is an typedef to std::string and it would lead to duplicate definition error
+ // That's why we try to resolve both types and check if they are the same, if they are we only generate
+ // vector<std::string> if not - both.
+ let vec_cv_string = self.gen_env.resolve_type("std::vector<cv::String>").expect("Can't resolve std::vector<cv::String>");
+ let vec_std_string = self.gen_env.resolve_type("std::vector<std::string>").expect("Can't resolve std::vector<std::string>");
+ if vec_cv_string.get_canonical_type() == vec_std_string.get_canonical_type() {
+ out.push(Box::new(ReturnTypeWrapper::new(
+ TypeRef::new(vec_std_string, self.gen_env),
+ self.gen_env,
+ DefinitionLocation::Module,
+ )));
+ } else {
+ out.push(Box::new(ReturnTypeWrapper::new(self.type_ref(), self.gen_env, DefinitionLocation::Module)));
+ }
+ } else {
out.push(Box::new(ReturnTypeWrapper::new(element_type.canonical_clang(), self.gen_env, DefinitionLocation::Type)));
out.push(Box::new(ReturnTypeWrapper::new(self.type_ref().canonical_clang(), self.gen_env, DefinitionLocation::Module)));
- if needs_ioa {
+ }
+ if is_data_type {
out.push(Box::new(ReturnTypeWrapper::new(
TypeRef::new(self.gen_env.resolve_type("cv::_InputArray").expect("Can't resolve _InputArray"), self.gen_env),
self.gen_env,
@@ -78,13 +103,6 @@ impl<'tu, 'g> Vector<'tu, 'g> {
DefinitionLocation::Custom(element_type.rust_module().into_owned()),
)));
}
- if needs_char_ptr {
- out.push(Box::new(ReturnTypeWrapper::new(
- TypeRef::new(self.gen_env.resolve_type("const char*").expect("Can't resolve _InputOutputArray"), self.gen_env),
- self.gen_env,
- DefinitionLocation::Custom(element_type.rust_module().into_owned()),
- )));
- }
out
}
}

MODIFY
src_cpp/ocvrs_resolve_types.hpp
src_cpp/ocvrs_resolve_types.hpp
#include "common.hpp"
+#include <vector>
/* Dummy namespace that contains types that will be used in the bindings generator to resolve clang::Type from
string. Due to limitations of libclang it's not possible to resolve arbitrary strings. That's why we pre-add
@@ -17,6 +18,12 @@ namespace ocvrs_resolve_types {
typedef unsigned int core4;
typedef double core5;
typedef const char* core6;
+ // return of String
+ typedef void* core7;
+
+ // handling vector of strings
+ typedef std::vector<cv::String> core8;
+ typedef std::vector<std::string> core9;
// for return of vector<DataType> types
typedef cv::_InputArray ioa1;

Sort out generation of string return type wrappers