Home > database >  Flutter platform channels pass "multi-data" to windows function
Flutter platform channels pass "multi-data" to windows function

Time:09-28

I am testing the FlutterUI Result

Thank you!

CodePudding user response:

You can only pass a single entity as argument or result, but that entity can be any of the supported types (whether primitive - int, double, etc - or complex - list or map).

The mapping between Dart and C (native for Windows) types is:

// std::monostate       -> null
// bool                 -> bool
// int32_t              -> int
// int64_t              -> int
// double               -> double
// std::string          -> String
// std::vector<uint8_t> -> Uint8List
// std::vector<int32_t> -> Int32List
// std::vector<int64_t> -> Int64List
// std::vector<float>   -> Float32List
// std::vector<double>  -> Float64List
// EncodableList        -> List
// EncodableMap         -> Map

(see encodable_value.h)

So, to send your two integers (fluval and data2) you could choose to put them in a Dart list (i.e. <int>[123, 456]) or a Dart map (i.e. {'fluval':123, 'data2':456}). At the native end, arguments will be either an EncodableList or EncodableMap.

Here's an example of how a complex Dart structure would appear at the native end:

//   {
//     'flag': true,
//     'name': 'Thing',
//     'values': [1, 2.0, 4],
//   }
// would correspond to:
//   EncodableValue(EncodableMap{
//       {EncodableValue("flag"), EncodableValue(true)},
//       {EncodableValue("name"), EncodableValue("Thing")},
//       {EncodableValue("values"), EncodableValue(EncodableList{
//                                      EncodableValue(1),
//                                      EncodableValue(2.0),
//                                      EncodableValue(4),
//                                  })},
//   })

The camera plugin has some example usage (to get the arguments as a map):

const auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());

In the same file, check out the two utility functions:

// Looks for |key| in |map|, returning the associated value if it is present, or
// a nullptr if not.
const EncodableValue* ValueOrNull(const EncodableMap& map, const char* key) {
  auto it = map.find(EncodableValue(key));
  if (it == map.end()) {
    return nullptr;
  }
  return &(it->second);
}

// Looks for |key| in |map|, returning the associated int64 value if it is
// present, or std::nullopt if not.
std::optional<int64_t> GetInt64ValueOrNull(const EncodableMap& map,
                                           const char* key) {
  auto value = ValueOrNull(map, key);
  if (!value) {
    return std::nullopt;
  }

  if (std::holds_alternative<int32_t>(*value)) {
    return static_cast<int64_t>(std::get<int32_t>(*value));
  }
  auto val64 = std::get_if<int64_t>(value);
  if (!val64) {
    return std::nullopt;
  }
  return *val64;
}

and their typical usage:

  const auto* camera_name =
      std::get_if<std::string>(ValueOrNull(args, kCameraNameKey));

  auto camera_id = GetInt64ValueOrNull(args, kCameraIdKey);
  • Related